diff --git a/api/system-current.txt b/api/system-current.txt index 6a71c04f4a2b8..6e04616fb8723 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2928,6 +2928,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;
+ }
+ }
}