From e17be8f3f5e6af1cd2688f579ab484725c350202 Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Mon, 3 Dec 2018 15:02:23 -0800 Subject: [PATCH] SubtitleData: add Builder in SubtileData and TimedMetaData Test: cts Bug: 112549021 Change-Id: I5142f0d414931cd151f9377c328b7c3947ec0cfe --- api/system-current.txt | 14 ++++ media/java/android/media/SubtitleData.java | 83 ++++++++++++++++++++- media/java/android/media/TimedMetaData.java | 76 ++++++++++++++++++- 3 files changed, 170 insertions(+), 3 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 62d446f7254ef..2e046a60ca99f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2926,6 +2926,20 @@ package android.media { method public void stop(); } + public static class SubtitleData.Builder { + ctor public SubtitleData.Builder(); + ctor public SubtitleData.Builder(android.media.SubtitleData); + method public android.media.SubtitleData build(); + method public android.media.SubtitleData.Builder setSubtitleData(int, long, long, byte[]); + } + + public static class TimedMetaData.Builder { + ctor public TimedMetaData.Builder(); + ctor public TimedMetaData.Builder(android.media.TimedMetaData); + method public android.media.TimedMetaData build(); + method public android.media.TimedMetaData.Builder setTimedMetaData(int, byte[]); + } + } package android.media.audiopolicy { diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java index ba37b9b663601..852babe1eceac 100644 --- a/media/java/android/media/SubtitleData.java +++ b/media/java/android/media/SubtitleData.java @@ -17,8 +17,11 @@ package android.media; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; +import java.util.Arrays; + /** * Class encapsulating subtitle data, as received through the * {@link MediaPlayer.OnSubtitleDataListener} interface. @@ -80,11 +83,11 @@ public final class SubtitleData } /** @hide */ - public SubtitleData(int trackIndex, long startTimeUs, long durationUs, byte[] data) { + public SubtitleData(int trackIndex, long startTimeUs, long durationUs, @NonNull byte[] data) { mTrackIndex = trackIndex; mStartTimeUs = startTimeUs; mDurationUs = durationUs; - mData = data; + mData = (data != null ? data : new byte[0]); } /** @@ -138,4 +141,80 @@ public final class SubtitleData return true; } + + /** + * Builder class for {@link SubtitleData} objects. + *

Here is an example where Builder is used to define the + * {@link SubtitleData}: + * + *

+     * SubtitleData sd = new SubtitleData.Builder()
+     *         .setSubtitleData(trackIndex, startTime, duration, data)
+     *         .build();
+     * 
+ * @hide + */ + @SystemApi + public static class Builder { + private int mTrackIndex; + private long mStartTimeUs; + private long mDurationUs; + private byte[] mData = new byte[0]; + + /** + * Constructs a new Builder with the defaults. + */ + public Builder() { + } + + /** + * Constructs a new Builder from a given {@link SubtitleData} instance + * @param sd the {@link SubtitleData} object whose data will be reused + * in the new Builder. It should not be null. The data array is copied. + */ + public Builder(@NonNull SubtitleData sd) { + if (sd == null) { + throw new IllegalArgumentException("null SubtitleData is not allowed"); + } + mTrackIndex = sd.mTrackIndex; + mStartTimeUs = sd.mStartTimeUs; + mDurationUs = sd.mDurationUs; + if (sd.mData != null) { + mData = Arrays.copyOf(sd.mData, sd.mData.length); + } + } + + /** + * Combines all of the fields that have been set and return a new + * {@link SubtitleData} object. IllegalStateException will be + * thrown if there is conflict between fields. + * + * @return a new {@link SubtitleData} object + */ + public @NonNull SubtitleData build() { + return new SubtitleData(mTrackIndex, mStartTimeUs, mDurationUs, mData); + } + + /** + * Sets the info of subtitle data. + * + * @param trackIndex the ParcelFileDescriptor for the file to play + * @param startTimeUs the start time in microsecond for the subtile data + * @param durationUs the duration in microsecond for the subtile data + * @param data the data array for the subtile data. It should not be null. + * No data copying is made. + * @return the same Builder instance. + */ + public @NonNull Builder setSubtitleData( + int trackIndex, long startTimeUs, long durationUs, @NonNull byte[] data) { + if (data == null) { + throw new IllegalArgumentException("null data is not allowed"); + } + mTrackIndex = trackIndex; + mStartTimeUs = startTimeUs; + mDurationUs = durationUs; + mData = data; + return this; + } + } } diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java index 97e6bfa170d8c..bcc18ef92f94f 100644 --- a/media/java/android/media/TimedMetaData.java +++ b/media/java/android/media/TimedMetaData.java @@ -16,8 +16,12 @@ package android.media; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; +import java.util.Arrays; + /** * Class that embodies one timed metadata access unit, including * @@ -50,7 +54,10 @@ public final class TimedMetaData { /** * @hide */ - public TimedMetaData(long timestampUs, byte[] metaData) { + public TimedMetaData(long timestampUs, @NonNull byte[] metaData) { + if (metaData == null) { + throw new IllegalArgumentException("null metaData is not allowed"); + } mTimestampUs = timestampUs; mMetaData = metaData; } @@ -83,4 +90,71 @@ public final class TimedMetaData { return true; } + + /** + * Builder class for {@link TimedMetaData} objects. + *

Here is an example where Builder is used to define the + * {@link TimedMetaData}: + * + *

+     * TimedMetaData tmd = new TimedMetaData.Builder()
+     *         .setTimedMetaData(timestamp, metaData)
+     *         .build();
+     * 
+ * @hide + */ + @SystemApi + public static class Builder { + private long mTimestampUs; + private byte[] mMetaData = new byte[0]; + + /** + * Constructs a new Builder with the defaults. + */ + public Builder() { + } + + /** + * Constructs a new Builder from a given {@link TimedMetaData} instance + * @param tmd the {@link TimedMetaData} object whose data will be reused + * in the new Builder. It should not be null. The metadata array is copied. + */ + public Builder(@NonNull TimedMetaData tmd) { + if (tmd == null) { + throw new IllegalArgumentException("null TimedMetaData is not allowed"); + } + mTimestampUs = tmd.mTimestampUs; + if (tmd.mMetaData != null) { + mMetaData = Arrays.copyOf(tmd.mMetaData, tmd.mMetaData.length); + } + } + + /** + * Combines all of the fields that have been set and return a new + * {@link TimedMetaData} object. IllegalStateException will be + * thrown if there is conflict between fields. + * + * @return a new {@link TimedMetaData} object + */ + public @NonNull TimedMetaData build() { + return new TimedMetaData(mTimestampUs, mMetaData); + } + + /** + * Sets the info of timed metadata. + * + * @param timestamp the timestamp in microsecond for the timed metadata + * @param metaData the metadata array for the timed metadata. No data copying is made. + * It should not be null. + * @return the same Builder instance. + */ + public @NonNull Builder setTimedMetaData(int timestamp, @NonNull byte[] metaData) { + if (metaData == null) { + throw new IllegalArgumentException("null metaData is not allowed"); + } + mTimestampUs = timestamp; + mMetaData = metaData; + return this; + } + } }