diff options
| -rw-r--r-- | core/api/current.txt | 147 | ||||
| -rw-r--r-- | core/api/test-current.txt | 14 | ||||
| -rw-r--r-- | media/java/android/media/metrics/NetworkEvent.java | 86 | ||||
| -rw-r--r-- | media/java/android/media/metrics/PlaybackComponent.java | 3 | ||||
| -rw-r--r-- | media/java/android/media/metrics/PlaybackMetrics.java | 101 | ||||
| -rw-r--r-- | media/java/android/media/metrics/PlaybackSession.java | 7 | ||||
| -rw-r--r-- | media/java/android/media/metrics/TrackChangeEvent.java | 229 | ||||
| -rw-r--r-- | services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java | 8 |
8 files changed, 441 insertions, 154 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 5f9743aa5e73..e357687527c2 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21000,7 +21000,7 @@ package android.media { method @NonNull public String getDiagnosticInfo(); } - public final class MediaCodec { + public final class MediaCodec implements android.media.metrics.PlaybackComponent { method public void configure(@Nullable android.media.MediaFormat, @Nullable android.view.Surface, @Nullable android.media.MediaCrypto, int); method public void configure(@Nullable android.media.MediaFormat, @Nullable android.view.Surface, int, @Nullable android.media.MediaDescrambler); method @NonNull public static android.media.MediaCodec createByCodecName(@NonNull String) throws java.io.IOException; @@ -21026,6 +21026,7 @@ package android.media { method @NonNull public android.media.MediaFormat getOutputFormat(int); method @NonNull public android.media.MediaCodec.OutputFrame getOutputFrame(int); method @Nullable public android.media.Image getOutputImage(int); + method public String getPlaybackId(); method @NonNull public android.media.MediaCodec.QueueRequest getQueueRequest(int); method @Nullable public static android.media.Image mapHardwareBuffer(@NonNull android.hardware.HardwareBuffer); method public void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException; @@ -21041,6 +21042,7 @@ package android.media { method public void setOnFrameRenderedListener(@Nullable android.media.MediaCodec.OnFrameRenderedListener, @Nullable android.os.Handler); method public void setOutputSurface(@NonNull android.view.Surface); method public void setParameters(@Nullable android.os.Bundle); + method public void setPlaybackId(@NonNull String); method public void setVideoScalingMode(int); method public void signalEndOfInputStream(); method public void start(); @@ -24114,6 +24116,34 @@ package android.media.metrics { field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL } + public final class NetworkEvent extends android.media.metrics.Event implements android.os.Parcelable { + method public int describeContents(); + method public int getNetworkType(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.NetworkEvent> CREATOR; + field public static final int NETWORK_TYPE_2G = 4; // 0x4 + field public static final int NETWORK_TYPE_3G = 5; // 0x5 + field public static final int NETWORK_TYPE_4G = 6; // 0x6 + field public static final int NETWORK_TYPE_5G_NSA = 7; // 0x7 + field public static final int NETWORK_TYPE_5G_SA = 8; // 0x8 + field public static final int NETWORK_TYPE_ETHERNET = 3; // 0x3 + field public static final int NETWORK_TYPE_NONE = 0; // 0x0 + field public static final int NETWORK_TYPE_OTHER = 1; // 0x1 + field public static final int NETWORK_TYPE_WIFI = 2; // 0x2 + } + + public static final class NetworkEvent.Builder { + ctor public NetworkEvent.Builder(); + method @NonNull public android.media.metrics.NetworkEvent build(); + method @NonNull public android.media.metrics.NetworkEvent.Builder setNetworkType(int); + method @NonNull public android.media.metrics.NetworkEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long); + } + + public interface PlaybackComponent { + method @NonNull public String getPlaybackId(); + method public void setPlaybackId(@NonNull String); + } + public final class PlaybackErrorEvent extends android.media.metrics.Event implements android.os.Parcelable { method public int describeContents(); method public int getErrorCode(); @@ -24134,11 +24164,78 @@ package android.media.metrics { method @NonNull public android.media.metrics.PlaybackErrorEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long); } + public final class PlaybackMetrics implements android.os.Parcelable { + method public int describeContents(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getAudioUnderrunCount(); + method public int getContentType(); + method public int getDrmType(); + method @NonNull public long[] getExperimentIds(); + method @IntRange(from=0xffffffff) public long getLocalBytesRead(); + method @IntRange(from=0xffffffff) public long getMediaDurationMillis(); + method @IntRange(from=0xffffffff) public long getNetworkBytesRead(); + method @IntRange(from=0xffffffff) public long getNetworkTransferDurationMillis(); + method public int getPlaybackType(); + method @Nullable public String getPlayerName(); + method @Nullable public String getPlayerVersion(); + method public int getStreamSource(); + method public int getStreamType(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getVideoFramesDropped(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getVideoFramesPlayed(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int CONTENT_TYPE_AD = 1; // 0x1 + field public static final int CONTENT_TYPE_MAIN = 0; // 0x0 + field public static final int CONTENT_TYPE_OTHER = 2; // 0x2 + field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.PlaybackMetrics> CREATOR; + field public static final int DRM_TYPE_CLEARKEY = 6; // 0x6 + field public static final int DRM_TYPE_NONE = 0; // 0x0 + field public static final int DRM_TYPE_OTHER = 1; // 0x1 + field public static final int DRM_TYPE_PLAY_READY = 2; // 0x2 + field public static final int DRM_TYPE_WIDEVINE_L1 = 3; // 0x3 + field public static final int DRM_TYPE_WIDEVINE_L3 = 4; // 0x4 + field public static final int DRM_TYPE_WV_L3_FALLBACK = 5; // 0x5 + field public static final int PLAYBACK_TYPE_LIVE = 1; // 0x1 + field public static final int PLAYBACK_TYPE_OTHER = 2; // 0x2 + field public static final int PLAYBACK_TYPE_VOD = 0; // 0x0 + field public static final int STREAM_SOURCE_DEVICE = 2; // 0x2 + field public static final int STREAM_SOURCE_MIXED = 3; // 0x3 + field public static final int STREAM_SOURCE_NETWORK = 1; // 0x1 + field public static final int STREAM_SOURCE_UNKNOWN = 0; // 0x0 + field public static final int STREAM_TYPE_DASH = 3; // 0x3 + field public static final int STREAM_TYPE_HLS = 4; // 0x4 + field public static final int STREAM_TYPE_OTHER = 1; // 0x1 + field public static final int STREAM_TYPE_PROGRESSIVE = 2; // 0x2 + field public static final int STREAM_TYPE_SS = 5; // 0x5 + field public static final int STREAM_TYPE_UNKNOWN = 0; // 0x0 + } + + public static final class PlaybackMetrics.Builder { + ctor public PlaybackMetrics.Builder(); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder addExperimentId(long); + method @NonNull public android.media.metrics.PlaybackMetrics build(); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setAudioUnderrunCount(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setContentType(int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setDrmType(int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setLocalBytesRead(@IntRange(from=0xffffffff) long); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setMediaDurationMillis(@IntRange(from=0xffffffff) long); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setNetworkBytesRead(@IntRange(from=0xffffffff) long); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setNetworkTransferDurationMillis(@IntRange(from=0xffffffff) long); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setPlaybackType(int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setPlayerName(@NonNull String); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setPlayerVersion(@NonNull String); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setStreamSource(int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setStreamType(int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setVideoFramesDropped(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.media.metrics.PlaybackMetrics.Builder setVideoFramesPlayed(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + } + public final class PlaybackSession implements java.lang.AutoCloseable { method public void close(); method @NonNull public String getId(); + method public void reportNetworkEvent(@NonNull android.media.metrics.NetworkEvent); method public void reportPlaybackErrorEvent(@NonNull android.media.metrics.PlaybackErrorEvent); + method public void reportPlaybackMetrics(@NonNull android.media.metrics.PlaybackMetrics); method public void reportPlaybackStateEvent(@NonNull android.media.metrics.PlaybackStateEvent); + method public void reportTrackChangeEvent(@NonNull android.media.metrics.TrackChangeEvent); } public final class PlaybackStateEvent extends android.media.metrics.Event implements android.os.Parcelable { @@ -24170,6 +24267,54 @@ package android.media.metrics { method @NonNull public android.media.metrics.PlaybackStateEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long); } + public final class TrackChangeEvent extends android.media.metrics.Event implements android.os.Parcelable { + ctor public TrackChangeEvent(int, int, @Nullable String, @Nullable String, @Nullable String, int, long, int, @Nullable String, @Nullable String, int, int, int, int); + method public int describeContents(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getBitrate(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getChannelCount(); + method @Nullable public String getCodecName(); + method @Nullable public String getContainerMimeType(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getHeight(); + method @Nullable public String getLanguage(); + method @Nullable public String getLanguageRegion(); + method @Nullable public String getSampleMimeType(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getSampleRate(); + method public int getTrackChangeReason(); + method public int getTrackState(); + method public int getTrackType(); + method @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) public int getWidth(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.TrackChangeEvent> CREATOR; + field public static final int TRACK_CHANGE_REASON_ADAPTIVE = 4; // 0x4 + field public static final int TRACK_CHANGE_REASON_INITIAL = 2; // 0x2 + field public static final int TRACK_CHANGE_REASON_MANUAL = 3; // 0x3 + field public static final int TRACK_CHANGE_REASON_OTHER = 1; // 0x1 + field public static final int TRACK_CHANGE_REASON_UNKNOWN = 0; // 0x0 + field public static final int TRACK_STATE_OFF = 0; // 0x0 + field public static final int TRACK_STATE_ON = 1; // 0x1 + field public static final int TRACK_TYPE_AUDIO = 0; // 0x0 + field public static final int TRACK_TYPE_TEXT = 2; // 0x2 + field public static final int TRACK_TYPE_VIDEO = 1; // 0x1 + } + + public static final class TrackChangeEvent.Builder { + ctor public TrackChangeEvent.Builder(int); + method @NonNull public android.media.metrics.TrackChangeEvent build(); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setBitrate(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setChannelCount(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setCodecName(@NonNull String); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setContainerMimeType(@NonNull String); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setHeight(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setLanguage(@NonNull String); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setLanguageRegion(@NonNull String); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setSampleMimeType(@NonNull String); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setSampleRate(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setTimeSinceCreatedMillis(@IntRange(from=0xffffffff) long); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setTrackChangeReason(int); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setTrackState(int); + method @NonNull public android.media.metrics.TrackChangeEvent.Builder setWidth(@IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) int); + } + } package android.media.midi { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index c03f660c21b8..ff96f92da2f5 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1232,11 +1232,6 @@ package android.media { method public void forceResourceLost(); } - public final class MediaCodec implements android.media.metrics.PlaybackComponent { - method public String getPlaybackId(); - method public void setPlaybackId(@NonNull String); - } - public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint { ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size); ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size); @@ -1311,15 +1306,6 @@ package android.media.audiopolicy { } -package android.media.metrics { - - public interface PlaybackComponent { - method @NonNull public String getPlaybackId(); - method public void setPlaybackId(@NonNull String); - } - -} - package android.media.tv { public final class TvInputManager { diff --git a/media/java/android/media/metrics/NetworkEvent.java b/media/java/android/media/metrics/NetworkEvent.java index a330bc0b66df..029edeb93374 100644 --- a/media/java/android/media/metrics/NetworkEvent.java +++ b/media/java/android/media/metrics/NetworkEvent.java @@ -17,6 +17,7 @@ package android.media.metrics; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; @@ -27,22 +28,30 @@ import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** - * Playback network event. - * @hide + * Media network event. */ -public final class NetworkEvent implements Parcelable { +public final class NetworkEvent extends Event implements Parcelable { + /** Network type is not specified. Default type. */ public static final int NETWORK_TYPE_NONE = 0; + /** Other network type */ public static final int NETWORK_TYPE_OTHER = 1; + /** Wi-Fi network */ public static final int NETWORK_TYPE_WIFI = 2; + /** Ethernet network */ public static final int NETWORK_TYPE_ETHERNET = 3; + /** 2G network */ public static final int NETWORK_TYPE_2G = 4; + /** 3G network */ public static final int NETWORK_TYPE_3G = 5; + /** 4G network */ public static final int NETWORK_TYPE_4G = 6; + /** 5G NSA network */ public static final int NETWORK_TYPE_5G_NSA = 7; + /** 5G SA network */ public static final int NETWORK_TYPE_5G_SA = 8; - private final int mType; - private final long mTimeSincePlaybackCreatedMillis; + private final int mNetworkType; + private final long mTimeSinceCreatedMillis; /** @hide */ @IntDef(prefix = "NETWORK_TYPE_", value = { @@ -61,6 +70,7 @@ public final class NetworkEvent implements Parcelable { /** * Network type to string. + * @hide */ public static String networkTypeToString(@NetworkType int value) { switch (value) { @@ -92,25 +102,34 @@ public final class NetworkEvent implements Parcelable { * * @hide */ - public NetworkEvent(@NetworkType int type, long timeSincePlaybackCreatedMillis) { - this.mType = type; - this.mTimeSincePlaybackCreatedMillis = timeSincePlaybackCreatedMillis; + public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis) { + this.mNetworkType = type; + this.mTimeSinceCreatedMillis = timeSinceCreatedMillis; } + /** + * Gets network type. + */ @NetworkType - public int getType() { - return mType; + public int getNetworkType() { + return mNetworkType; } - public long getTimeSincePlaybackCreatedMillis() { - return mTimeSincePlaybackCreatedMillis; + /** + * Gets timestamp since the creation in milliseconds. + * @return the timestamp since the creation in milliseconds, or -1 if unknown. + */ + @Override + @IntRange(from = -1) + public long getTimeSinceCreatedMillis() { + return mTimeSinceCreatedMillis; } @Override public String toString() { return "NetworkEvent { " - + "type = " + mType + ", " - + "timeSincePlaybackCreatedMillis = " + mTimeSincePlaybackCreatedMillis + + "networkType = " + mNetworkType + ", " + + "timeSinceCreatedMillis = " + mTimeSinceCreatedMillis + " }"; } @@ -119,19 +138,19 @@ public final class NetworkEvent implements Parcelable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NetworkEvent that = (NetworkEvent) o; - return mType == that.mType - && mTimeSincePlaybackCreatedMillis == that.mTimeSincePlaybackCreatedMillis; + return mNetworkType == that.mNetworkType + && mTimeSinceCreatedMillis == that.mTimeSinceCreatedMillis; } @Override public int hashCode() { - return Objects.hash(mType, mTimeSincePlaybackCreatedMillis); + return Objects.hash(mNetworkType, mTimeSinceCreatedMillis); } @Override public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { - dest.writeInt(mType); - dest.writeLong(mTimeSincePlaybackCreatedMillis); + dest.writeInt(mNetworkType); + dest.writeLong(mTimeSinceCreatedMillis); } @Override @@ -142,12 +161,15 @@ public final class NetworkEvent implements Parcelable { /** @hide */ /* package-private */ NetworkEvent(@NonNull android.os.Parcel in) { int type = in.readInt(); - long timeSincePlaybackCreatedMillis = in.readLong(); + long timeSinceCreatedMillis = in.readLong(); - this.mType = type; - this.mTimeSincePlaybackCreatedMillis = timeSincePlaybackCreatedMillis; + this.mNetworkType = type; + this.mTimeSinceCreatedMillis = timeSinceCreatedMillis; } + /** + * Used to read a NetworkEvent from a Parcel. + */ public static final @NonNull Parcelable.Creator<NetworkEvent> CREATOR = new Parcelable.Creator<NetworkEvent>() { @Override @@ -165,13 +187,11 @@ public final class NetworkEvent implements Parcelable { * A builder for {@link NetworkEvent} */ public static final class Builder { - private int mType; - private long mTimeSincePlaybackCreatedMillis; + private int mNetworkType = NETWORK_TYPE_NONE; + private long mTimeSinceCreatedMillis = -1; /** * Creates a new Builder. - * - * @hide */ public Builder() { } @@ -179,24 +199,24 @@ public final class NetworkEvent implements Parcelable { /** * Sets network type. */ - public @NonNull Builder setType(@NetworkType int value) { - mType = value; + public @NonNull Builder setNetworkType(@NetworkType int value) { + mNetworkType = value; return this; } /** * Sets timestamp since the creation in milliseconds. + * @param value the timestamp since the creation in milliseconds. + * -1 indicates the value is unknown. */ - public @NonNull Builder setTimeSincePlaybackCreatedMillis(long value) { - mTimeSincePlaybackCreatedMillis = value; + public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) { + mTimeSinceCreatedMillis = value; return this; } /** Builds the instance. */ public @NonNull NetworkEvent build() { - NetworkEvent o = new NetworkEvent( - mType, - mTimeSincePlaybackCreatedMillis); + NetworkEvent o = new NetworkEvent(mNetworkType, mTimeSinceCreatedMillis); return o; } } diff --git a/media/java/android/media/metrics/PlaybackComponent.java b/media/java/android/media/metrics/PlaybackComponent.java index 94e55b4843c1..1cadf3be38ee 100644 --- a/media/java/android/media/metrics/PlaybackComponent.java +++ b/media/java/android/media/metrics/PlaybackComponent.java @@ -17,13 +17,10 @@ package android.media.metrics; import android.annotation.NonNull; -import android.annotation.TestApi; /** * Interface for playback related components used by playback metrics. - * @hide */ -@TestApi public interface PlaybackComponent { /** diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java index 070b4e4aa14b..4aa61662ba52 100644 --- a/media/java/android/media/metrics/PlaybackMetrics.java +++ b/media/java/android/media/metrics/PlaybackMetrics.java @@ -17,6 +17,7 @@ package android.media.metrics; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; @@ -33,35 +34,57 @@ import java.util.Objects; /** * This class is used to store playback data. - * @hide */ public final class PlaybackMetrics implements Parcelable { - // TODO(b/177209128): JavaDoc for the constants. + /** Unknown stream source. */ public static final int STREAM_SOURCE_UNKNOWN = 0; + /** Stream from network. */ public static final int STREAM_SOURCE_NETWORK = 1; + /** Stream from device. */ public static final int STREAM_SOURCE_DEVICE = 2; + /** Stream from more than one sources. */ public static final int STREAM_SOURCE_MIXED = 3; + /** Unknown stream type. */ public static final int STREAM_TYPE_UNKNOWN = 0; + /** Other stream type. */ public static final int STREAM_TYPE_OTHER = 1; + /** Progressive stream type. */ public static final int STREAM_TYPE_PROGRESSIVE = 2; + /** DASH (Dynamic Adaptive Streaming over HTTP) stream type. */ public static final int STREAM_TYPE_DASH = 3; + /** HLS (HTTP Live Streaming) stream type. */ public static final int STREAM_TYPE_HLS = 4; + /** SS (HTTP Smooth Streaming) stream type. */ public static final int STREAM_TYPE_SS = 5; + /** VOD (Video on Demand) playback type. */ public static final int PLAYBACK_TYPE_VOD = 0; + /** Live playback type. */ public static final int PLAYBACK_TYPE_LIVE = 1; + /** Other playback type. */ public static final int PLAYBACK_TYPE_OTHER = 2; + /** DRM is not used. */ public static final int DRM_TYPE_NONE = 0; + /** Other DRM type. */ public static final int DRM_TYPE_OTHER = 1; + /** Play ready DRM type. */ public static final int DRM_TYPE_PLAY_READY = 2; + /** Widevine L1 DRM type. */ public static final int DRM_TYPE_WIDEVINE_L1 = 3; + /** Widevine L3 DRM type. */ public static final int DRM_TYPE_WIDEVINE_L3 = 4; - // TODO: add DRM_TYPE_CLEARKEY + /** Widevine L3 fallback DRM type. */ + public static final int DRM_TYPE_WV_L3_FALLBACK = 5; + /** Clear key DRM type. */ + public static final int DRM_TYPE_CLEARKEY = 6; + /** Main contents. */ public static final int CONTENT_TYPE_MAIN = 0; + /** Advertisement contents. */ public static final int CONTENT_TYPE_AD = 1; + /** Other contents. */ public static final int CONTENT_TYPE_OTHER = 2; @@ -102,7 +125,9 @@ public final class PlaybackMetrics implements Parcelable { DRM_TYPE_OTHER, DRM_TYPE_PLAY_READY, DRM_TYPE_WIDEVINE_L1, - DRM_TYPE_WIDEVINE_L3 + DRM_TYPE_WIDEVINE_L3, + DRM_TYPE_WV_L3_FALLBACK, + DRM_TYPE_CLEARKEY }) @Retention(RetentionPolicy.SOURCE) public @interface DrmType {} @@ -173,6 +198,11 @@ public final class PlaybackMetrics implements Parcelable { this.mNetworkTransferDurationMillis = networkTransferDurationMillis; } + /** + * Gets the media duration in milliseconds. + * @return the media duration in milliseconds, or -1 if unknown. + */ + @IntRange(from = -1) public long getMediaDurationMillis() { return mMediaDurationMillis; } @@ -241,28 +271,36 @@ public final class PlaybackMetrics implements Parcelable { /** * Gets video frames played. + * @return the video frames played, or -1 if unknown. */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getVideoFramesPlayed() { return mVideoFramesPlayed; } /** * Gets video frames dropped. + * @return the video frames dropped, or -1 if unknown. */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getVideoFramesDropped() { return mVideoFramesDropped; } /** * Gets audio underrun count. + * @return the audio underrun count, or -1 if unknown. */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getAudioUnderrunCount() { return mAudioUnderrunCount; } /** * Gets number of network bytes read. + * @return the number of network bytes read, or -1 if unknown. */ + @IntRange(from = -1) public long getNetworkBytesRead() { return mNetworkBytesRead; } @@ -270,6 +308,7 @@ public final class PlaybackMetrics implements Parcelable { /** * Gets number of local bytes read. */ + @IntRange(from = -1) public long getLocalBytesRead() { return mLocalBytesRead; } @@ -277,6 +316,7 @@ public final class PlaybackMetrics implements Parcelable { /** * Gets network transfer duration in milliseconds. */ + @IntRange(from = -1) public long getNetworkTransferDurationMillis() { return mNetworkTransferDurationMillis; } @@ -415,34 +455,33 @@ public final class PlaybackMetrics implements Parcelable { */ public static final class Builder { - private long mMediaDurationMillis; - private int mStreamSource; - private int mStreamType; - private int mPlaybackType; - private int mDrmType; - private int mContentType; + private long mMediaDurationMillis = -1; + private int mStreamSource = STREAM_SOURCE_UNKNOWN; + private int mStreamType = STREAM_TYPE_UNKNOWN; + private int mPlaybackType = PLAYBACK_TYPE_OTHER; + private int mDrmType = DRM_TYPE_NONE; + private int mContentType = CONTENT_TYPE_OTHER; private @Nullable String mPlayerName; private @Nullable String mPlayerVersion; private @NonNull List<Long> mExperimentIds = new ArrayList<>(); - private int mVideoFramesPlayed; - private int mVideoFramesDropped; - private int mAudioUnderrunCount; - private long mNetworkBytesRead; - private long mLocalBytesRead; - private long mNetworkTransferDurationMillis; + private int mVideoFramesPlayed = -1; + private int mVideoFramesDropped = -1; + private int mAudioUnderrunCount = -1; + private long mNetworkBytesRead = -1; + private long mLocalBytesRead = -1; + private long mNetworkTransferDurationMillis = -1; /** * Creates a new Builder. - * - * @hide */ public Builder() { } /** * Sets the media duration in milliseconds. + * @param value the media duration in milliseconds. -1 indicates the value is unknown. */ - public @NonNull Builder setMediaDurationMillis(long value) { + public @NonNull Builder setMediaDurationMillis(@IntRange(from = -1) long value) { mMediaDurationMillis = value; return this; } @@ -474,7 +513,7 @@ public final class PlaybackMetrics implements Parcelable { /** * Sets the DRM type. */ - public @NonNull Builder setDrmType(@StreamType int value) { + public @NonNull Builder setDrmType(@DrmType int value) { mDrmType = value; return this; } @@ -513,48 +552,58 @@ public final class PlaybackMetrics implements Parcelable { /** * Sets the video frames played. + * @param value the video frames played. -1 indicates the value is unknown. */ - public @NonNull Builder setVideoFramesPlayed(int value) { + public @NonNull Builder setVideoFramesPlayed( + @IntRange(from = -1, to = Integer.MAX_VALUE) int value) { mVideoFramesPlayed = value; return this; } /** * Sets the video frames dropped. + * @param value the video frames dropped. -1 indicates the value is unknown. */ - public @NonNull Builder setVideoFramesDropped(int value) { + public @NonNull Builder setVideoFramesDropped( + @IntRange(from = -1, to = Integer.MAX_VALUE) int value) { mVideoFramesDropped = value; return this; } /** * Sets the audio underrun count. + * @param value the audio underrun count. -1 indicates the value is unknown. */ - public @NonNull Builder setAudioUnderrunCount(int value) { + public @NonNull Builder setAudioUnderrunCount( + @IntRange(from = -1, to = Integer.MAX_VALUE) int value) { mAudioUnderrunCount = value; return this; } /** * Sets the number of network bytes read. + * @param value the number of network bytes read. -1 indicates the value is unknown. */ - public @NonNull Builder setNetworkBytesRead(long value) { + public @NonNull Builder setNetworkBytesRead(@IntRange(from = -1) long value) { mNetworkBytesRead = value; return this; } /** * Sets the number of local bytes read. + * @param value the number of local bytes read. -1 indicates the value is unknown. */ - public @NonNull Builder setLocalBytesRead(long value) { + public @NonNull Builder setLocalBytesRead(@IntRange(from = -1) long value) { mLocalBytesRead = value; return this; } /** * Sets the network transfer duration in milliseconds. + * @param value the network transfer duration in milliseconds. + * -1 indicates the value is unknown. */ - public @NonNull Builder setNetworkTransferDurationMillis(long value) { + public @NonNull Builder setNetworkTransferDurationMillis(@IntRange(from = -1) long value) { mNetworkTransferDurationMillis = value; return this; } diff --git a/media/java/android/media/metrics/PlaybackSession.java b/media/java/android/media/metrics/PlaybackSession.java index 4cb957f4e597..4ee8a45fe196 100644 --- a/media/java/android/media/metrics/PlaybackSession.java +++ b/media/java/android/media/metrics/PlaybackSession.java @@ -45,7 +45,6 @@ public final class PlaybackSession implements AutoCloseable { /** * Reports playback metrics. - * @hide */ public void reportPlaybackMetrics(@NonNull PlaybackMetrics metrics) { mManager.reportPlaybackMetrics(mId, metrics); @@ -60,9 +59,8 @@ public final class PlaybackSession implements AutoCloseable { /** * Reports network event. - * @hide */ - public void reportNetworkEvent(NetworkEvent event) { + public void reportNetworkEvent(@NonNull NetworkEvent event) { mManager.reportNetworkEvent(mId, event); } @@ -75,9 +73,8 @@ public final class PlaybackSession implements AutoCloseable { /** * Reports track change event. - * @hide */ - public void reportTrackChangeEvent(TrackChangeEvent event) { + public void reportTrackChangeEvent(@NonNull TrackChangeEvent event) { mManager.reportTrackChangeEvent(mId, event); } diff --git a/media/java/android/media/metrics/TrackChangeEvent.java b/media/java/android/media/metrics/TrackChangeEvent.java index fff0e36c062a..ef25357457c5 100644 --- a/media/java/android/media/metrics/TrackChangeEvent.java +++ b/media/java/android/media/metrics/TrackChangeEvent.java @@ -17,6 +17,7 @@ package android.media.metrics; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; @@ -28,20 +29,29 @@ import java.util.Objects; /** * Playback track change event. - * @hide */ -public final class TrackChangeEvent implements Parcelable { +public final class TrackChangeEvent extends Event implements Parcelable { + /** The track is off. */ public static final int TRACK_STATE_OFF = 0; + /** The track is on. */ public static final int TRACK_STATE_ON = 1; + /** Unknown track change reason. */ public static final int TRACK_CHANGE_REASON_UNKNOWN = 0; + /** Other track change reason. */ public static final int TRACK_CHANGE_REASON_OTHER = 1; + /** Track change reason for initial state. */ public static final int TRACK_CHANGE_REASON_INITIAL = 2; + /** Track change reason for manual changes. */ public static final int TRACK_CHANGE_REASON_MANUAL = 3; + /** Track change reason for adaptive changes. */ public static final int TRACK_CHANGE_REASON_ADAPTIVE = 4; + /** Audio track. */ public static final int TRACK_TYPE_AUDIO = 0; + /** Video track. */ public static final int TRACK_TYPE_VIDEO = 1; + /** Text track. */ public static final int TRACK_TYPE_TEXT = 2; private final int mState; @@ -50,7 +60,7 @@ public final class TrackChangeEvent implements Parcelable { private final @Nullable String mSampleMimeType; private final @Nullable String mCodecName; private final int mBitrate; - private final long mTimeSincePlaybackCreatedMillis; + private final long mTimeSinceCreatedMillis; private final int mType; private final @Nullable String mLanguage; private final @Nullable String mLanguageRegion; @@ -96,7 +106,7 @@ public final class TrackChangeEvent implements Parcelable { @Nullable String sampleMimeType, @Nullable String codecName, int bitrate, - long timeSincePlaybackCreatedMillis, + long timeSinceCreatedMillis, int type, @Nullable String language, @Nullable String languageRegion, @@ -110,7 +120,7 @@ public final class TrackChangeEvent implements Parcelable { this.mSampleMimeType = sampleMimeType; this.mCodecName = codecName; this.mBitrate = bitrate; - this.mTimeSincePlaybackCreatedMillis = timeSincePlaybackCreatedMillis; + this.mTimeSinceCreatedMillis = timeSinceCreatedMillis; this.mType = type; this.mLanguage = language; this.mLanguageRegion = languageRegion; @@ -120,34 +130,60 @@ public final class TrackChangeEvent implements Parcelable { this.mHeight = height; } + /** + * Gets track state. + */ @TrackState public int getTrackState() { return mState; } + /** + * Gets track change reason. + */ @TrackChangeReason public int getTrackChangeReason() { return mReason; } + /** + * Gets container MIME type. + */ public @Nullable String getContainerMimeType() { return mContainerMimeType; } + /** + * Gets the MIME type of the video/audio/text samples. + */ public @Nullable String getSampleMimeType() { return mSampleMimeType; } + /** + * Gets codec name. + */ public @Nullable String getCodecName() { return mCodecName; } + /** + * Gets bitrate. + * @return the bitrate, or -1 if unknown. + */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getBitrate() { return mBitrate; } - public long getTimeSincePlaybackCreatedMillis() { - return mTimeSincePlaybackCreatedMillis; + /** + * Gets timestamp since the creation in milliseconds. + * @return the timestamp since the creation in milliseconds, or -1 if unknown. + */ + @Override + @IntRange(from = -1) + public long getTimeSinceCreatedMillis() { + return mTimeSinceCreatedMillis; } @TrackType @@ -155,26 +191,55 @@ public final class TrackChangeEvent implements Parcelable { return mType; } + /** + * Gets language code. + * @return a two-letter ISO 639-1 language code. + */ public @Nullable String getLanguage() { return mLanguage; } + + /** + * Gets language region code. + * @return an IETF BCP 47 optional language region subtag based on a two-letter country code. + */ public @Nullable String getLanguageRegion() { return mLanguageRegion; } + /** + * Gets channel count. + * @return the channel count, or -1 if unknown. + */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getChannelCount() { return mChannelCount; } + /** + * Gets sample rate. + * @return the sample rate, or -1 if unknown. + */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getSampleRate() { return mSampleRate; } + /** + * Gets video width. + * @return the video width, or -1 if unknown. + */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getWidth() { return mWidth; } + /** + * Gets video height. + * @return the video height, or -1 if unknown. + */ + @IntRange(from = -1, to = Integer.MAX_VALUE) public int getHeight() { return mHeight; } @@ -194,7 +259,7 @@ public final class TrackChangeEvent implements Parcelable { if (mSampleMimeType != null) dest.writeString(mSampleMimeType); if (mCodecName != null) dest.writeString(mCodecName); dest.writeInt(mBitrate); - dest.writeLong(mTimeSincePlaybackCreatedMillis); + dest.writeLong(mTimeSinceCreatedMillis); dest.writeInt(mType); if (mLanguage != null) dest.writeString(mLanguage); if (mLanguageRegion != null) dest.writeString(mLanguageRegion); @@ -218,7 +283,7 @@ public final class TrackChangeEvent implements Parcelable { String sampleMimeType = (flg & 0x8) == 0 ? null : in.readString(); String codecName = (flg & 0x10) == 0 ? null : in.readString(); int bitrate = in.readInt(); - long timeSincePlaybackCreatedMillis = in.readLong(); + long timeSinceCreatedMillis = in.readLong(); int type = in.readInt(); String language = (flg & 0x100) == 0 ? null : in.readString(); String languageRegion = (flg & 0x200) == 0 ? null : in.readString(); @@ -233,7 +298,7 @@ public final class TrackChangeEvent implements Parcelable { this.mSampleMimeType = sampleMimeType; this.mCodecName = codecName; this.mBitrate = bitrate; - this.mTimeSincePlaybackCreatedMillis = timeSincePlaybackCreatedMillis; + this.mTimeSinceCreatedMillis = timeSinceCreatedMillis; this.mType = type; this.mLanguage = language; this.mLanguageRegion = languageRegion; @@ -256,38 +321,24 @@ public final class TrackChangeEvent implements Parcelable { } }; - - - // Code below generated by codegen v1.0.22. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/media/java/android/media/metrics/TrackChangeEvent.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - @Override public String toString() { - return "TrackChangeEvent { " + - "state = " + mState + ", " + - "reason = " + mReason + ", " + - "containerMimeType = " + mContainerMimeType + ", " + - "sampleMimeType = " + mSampleMimeType + ", " + - "codecName = " + mCodecName + ", " + - "bitrate = " + mBitrate + ", " + - "timeSincePlaybackCreatedMillis = " + mTimeSincePlaybackCreatedMillis + ", " + - "type = " + mType + ", " + - "language = " + mLanguage + ", " + - "languageRegion = " + mLanguageRegion + ", " + - "channelCount = " + mChannelCount + ", " + - "sampleRate = " + mSampleRate + ", " + - "width = " + mWidth + ", " + - "height = " + mHeight + - " }"; + return "TrackChangeEvent { " + + "state = " + mState + ", " + + "reason = " + mReason + ", " + + "containerMimeType = " + mContainerMimeType + ", " + + "sampleMimeType = " + mSampleMimeType + ", " + + "codecName = " + mCodecName + ", " + + "bitrate = " + mBitrate + ", " + + "timeSinceCreatedMillis = " + mTimeSinceCreatedMillis + ", " + + "type = " + mType + ", " + + "language = " + mLanguage + ", " + + "languageRegion = " + mLanguageRegion + ", " + + "channelCount = " + mChannelCount + ", " + + "sampleRate = " + mSampleRate + ", " + + "width = " + mWidth + ", " + + "height = " + mHeight + + " }"; } @Override @@ -301,7 +352,7 @@ public final class TrackChangeEvent implements Parcelable { && Objects.equals(mSampleMimeType, that.mSampleMimeType) && Objects.equals(mCodecName, that.mCodecName) && mBitrate == that.mBitrate - && mTimeSincePlaybackCreatedMillis == that.mTimeSincePlaybackCreatedMillis + && mTimeSinceCreatedMillis == that.mTimeSinceCreatedMillis && mType == that.mType && Objects.equals(mLanguage, that.mLanguage) && Objects.equals(mLanguageRegion, that.mLanguageRegion) @@ -314,7 +365,7 @@ public final class TrackChangeEvent implements Parcelable { @Override public int hashCode() { return Objects.hash(mState, mReason, mContainerMimeType, mSampleMimeType, mCodecName, - mBitrate, mTimeSincePlaybackCreatedMillis, mType, mLanguage, mLanguageRegion, + mBitrate, mTimeSinceCreatedMillis, mType, mLanguage, mLanguageRegion, mChannelCount, mSampleRate, mWidth, mHeight); } @@ -323,32 +374,33 @@ public final class TrackChangeEvent implements Parcelable { */ public static final class Builder { // TODO: check track type for the setters. - private int mState; - private int mReason; + private int mState = TRACK_STATE_OFF; + private int mReason = TRACK_CHANGE_REASON_UNKNOWN; private @Nullable String mContainerMimeType; private @Nullable String mSampleMimeType; private @Nullable String mCodecName; - private int mBitrate; - private long mTimeSincePlaybackCreatedMillis; - private int mType; + private int mBitrate = -1; + private long mTimeSinceCreatedMillis = -1; + private final int mType; private @Nullable String mLanguage; private @Nullable String mLanguageRegion; - private int mChannelCount; - private int mSampleRate; - private int mWidth; - private int mHeight; + private int mChannelCount = -1; + private int mSampleRate = -1; + private int mWidth = -1; + private int mHeight = -1; private long mBuilderFieldsSet = 0L; /** * Creates a new Builder. - * - * @hide */ public Builder(int type) { mType = type; } + /** + * Sets track state. + */ public @NonNull Builder setTrackState(@TrackState int value) { checkNotUsed(); mBuilderFieldsSet |= 0x1; @@ -356,6 +408,9 @@ public final class TrackChangeEvent implements Parcelable { return this; } + /** + * Sets track change reason. + */ public @NonNull Builder setTrackChangeReason(@TrackChangeReason int value) { checkNotUsed(); mBuilderFieldsSet |= 0x2; @@ -363,6 +418,9 @@ public final class TrackChangeEvent implements Parcelable { return this; } + /** + * Sets container MIME type. + */ public @NonNull Builder setContainerMimeType(@NonNull String value) { checkNotUsed(); mBuilderFieldsSet |= 0x4; @@ -370,6 +428,9 @@ public final class TrackChangeEvent implements Parcelable { return this; } + /** + * Sets the MIME type of the video/audio/text samples. + */ public @NonNull Builder setSampleMimeType(@NonNull String value) { checkNotUsed(); mBuilderFieldsSet |= 0x8; @@ -377,6 +438,9 @@ public final class TrackChangeEvent implements Parcelable { return this; } + /** + * Sets codec name. + */ public @NonNull Builder setCodecName(@NonNull String value) { checkNotUsed(); mBuilderFieldsSet |= 0x10; @@ -384,27 +448,33 @@ public final class TrackChangeEvent implements Parcelable { return this; } - public @NonNull Builder setBitrate(int value) { + /** + * Sets bitrate in bits per second. + * @param value the bitrate in bits per second. -1 indicates the value is unknown. + */ + public @NonNull Builder setBitrate(@IntRange(from = -1, to = Integer.MAX_VALUE) int value) { checkNotUsed(); mBuilderFieldsSet |= 0x20; mBitrate = value; return this; } - public @NonNull Builder setTimeSincePlaybackCreatedMillis(long value) { + /** + * Sets timestamp since the creation in milliseconds. + * @param value the timestamp since the creation in milliseconds. + * -1 indicates the value is unknown. + */ + public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) { checkNotUsed(); mBuilderFieldsSet |= 0x40; - mTimeSincePlaybackCreatedMillis = value; - return this; - } - - public @NonNull Builder setTrackType(@TrackType int value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x80; - mType = value; + mTimeSinceCreatedMillis = value; return this; } + /** + * Sets language code. + * @param value a two-letter ISO 639-1 language code. + */ public @NonNull Builder setLanguage(@NonNull String value) { checkNotUsed(); mBuilderFieldsSet |= 0x100; @@ -412,6 +482,11 @@ public final class TrackChangeEvent implements Parcelable { return this; } + /** + * Sets language region code. + * @param value an IETF BCP 47 optional language region subtag based on a two-letter country + * code. + */ public @NonNull Builder setLanguageRegion(@NonNull String value) { checkNotUsed(); mBuilderFieldsSet |= 0x200; @@ -419,28 +494,46 @@ public final class TrackChangeEvent implements Parcelable { return this; } - public @NonNull Builder setChannelCount(int value) { + /** + * Sets channel count. + * @param value the channel count. -1 indicates the value is unknown. + */ + public @NonNull Builder setChannelCount( + @IntRange(from = -1, to = Integer.MAX_VALUE) int value) { checkNotUsed(); mBuilderFieldsSet |= 0x400; mChannelCount = value; return this; } - public @NonNull Builder setSampleRate(int value) { + /** + * Sets sample rate. + * @param value the sample rate. -1 indicates the value is unknown. + */ + public @NonNull Builder setSampleRate( + @IntRange(from = -1, to = Integer.MAX_VALUE) int value) { checkNotUsed(); mBuilderFieldsSet |= 0x800; mSampleRate = value; return this; } - public @NonNull Builder setWidth(int value) { + /** + * Sets video width. + * @param value the video width. -1 indicates the value is unknown. + */ + public @NonNull Builder setWidth(@IntRange(from = -1, to = Integer.MAX_VALUE) int value) { checkNotUsed(); mBuilderFieldsSet |= 0x1000; mWidth = value; return this; } - public @NonNull Builder setHeight(int value) { + /** + * Sets video height. + * @param value the video height. -1 indicates the value is unknown. + */ + public @NonNull Builder setHeight(@IntRange(from = -1, to = Integer.MAX_VALUE) int value) { checkNotUsed(); mBuilderFieldsSet |= 0x2000; mHeight = value; @@ -459,7 +552,7 @@ public final class TrackChangeEvent implements Parcelable { mSampleMimeType, mCodecName, mBitrate, - mTimeSincePlaybackCreatedMillis, + mTimeSinceCreatedMillis, mType, mLanguage, mLanguageRegion, diff --git a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java index 4f4b4f259762..639dda6f8981 100644 --- a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java +++ b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java @@ -121,8 +121,8 @@ public final class MediaMetricsManagerService extends SystemService { StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(321) .writeString(sessionId) - .writeInt(event.getType()) - .writeLong(event.getTimeSincePlaybackCreatedMillis()) + .writeInt(event.getNetworkType()) + .writeLong(event.getTimeSinceCreatedMillis()) .usePooledBuffer() .build(); StatsLog.write(statsEvent); @@ -132,7 +132,7 @@ public final class MediaMetricsManagerService extends SystemService { public void reportTrackChangeEvent( String sessionId, TrackChangeEvent event, int userId) { StatsEvent statsEvent = StatsEvent.newBuilder() - .setAtomId(321) + .setAtomId(324) .writeString(sessionId) .writeInt(event.getTrackState()) .writeInt(event.getTrackChangeReason()) @@ -140,7 +140,7 @@ public final class MediaMetricsManagerService extends SystemService { .writeString(event.getSampleMimeType()) .writeString(event.getCodecName()) .writeInt(event.getBitrate()) - .writeLong(event.getTimeSincePlaybackCreatedMillis()) + .writeLong(event.getTimeSinceCreatedMillis()) .writeInt(event.getTrackType()) .writeString(event.getLanguage()) .writeString(event.getLanguageRegion()) |