Loading api/current.txt +12 −45 Original line number Diff line number Diff line Loading @@ -23707,17 +23707,6 @@ package android.media { method public void onTearDown(@NonNull android.media.AudioTrack); } public class CallbackDataSourceDesc extends android.media.DataSourceDesc { method @NonNull public android.media.DataSourceCallback getDataSourceCallback(); } public static class CallbackDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.CallbackDataSourceDesc.Builder> { ctor public CallbackDataSourceDesc.Builder(); ctor public CallbackDataSourceDesc.Builder(@Nullable android.media.CallbackDataSourceDesc); method @NonNull public android.media.CallbackDataSourceDesc build(); method @NonNull public android.media.CallbackDataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback); } public class CamcorderProfile { method public static android.media.CamcorderProfile get(int); method public static android.media.CamcorderProfile get(int, int); Loading Loading @@ -23784,10 +23773,18 @@ package android.media { field public static final long POSITION_UNKNOWN = 576460752303423L; // 0x20c49ba5e353fL } protected static class DataSourceDesc.BuilderBase<T extends android.media.DataSourceDesc.BuilderBase> { method @NonNull public T setEndPosition(long); method @NonNull public T setMediaId(@Nullable String); method @NonNull public T setStartPosition(long); public static final class DataSourceDesc.Builder { ctor public DataSourceDesc.Builder(); ctor public DataSourceDesc.Builder(@Nullable android.media.DataSourceDesc); method @NonNull public android.media.DataSourceDesc build(); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback); method @NonNull public android.media.DataSourceDesc.Builder setEndPosition(long); method @NonNull public android.media.DataSourceDesc.Builder setMediaId(@Nullable String); method @NonNull public android.media.DataSourceDesc.Builder setStartPosition(long); } public final class DeniedByServerException extends android.media.MediaDrmException { Loading Loading @@ -23992,21 +23989,6 @@ package android.media { field public static final int EULER_Z = 2; // 0x2 } public class FileDataSourceDesc extends android.media.DataSourceDesc { method public long getLength(); method public long getOffset(); method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor(); field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL } public static class FileDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.FileDataSourceDesc.Builder> { ctor public FileDataSourceDesc.Builder(); ctor public FileDataSourceDesc.Builder(@Nullable android.media.FileDataSourceDesc); method @NonNull public android.media.FileDataSourceDesc build(); method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); } public abstract class Image implements java.lang.AutoCloseable { method public abstract void close(); method public android.graphics.Rect getCropRect(); Loading Loading @@ -26641,21 +26623,6 @@ package android.media { ctor public UnsupportedSchemeException(String); } public class UriDataSourceDesc extends android.media.DataSourceDesc { method @NonNull public android.content.Context getContext(); method @Nullable public java.util.List<java.net.HttpCookie> getCookies(); method @Nullable public java.util.Map<java.lang.String,java.lang.String> getHeaders(); method @NonNull public android.net.Uri getUri(); } public static class UriDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.UriDataSourceDesc.Builder> { ctor public UriDataSourceDesc.Builder(); ctor public UriDataSourceDesc.Builder(@Nullable android.media.UriDataSourceDesc); method @NonNull public android.media.UriDataSourceDesc build(); method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri); method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>); } public interface VolumeAutomation { method @NonNull public android.media.VolumeShaper createVolumeShaper(@NonNull android.media.VolumeShaper.Configuration); } api/test-current.txt +17 −0 Original line number Diff line number Diff line Loading @@ -1078,6 +1078,17 @@ package android.media { method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int); } public class CallbackDataSourceDesc extends android.media.DataSourceDesc { method @NonNull public android.media.DataSourceCallback getDataSourceCallback(); } public class FileDataSourceDesc extends android.media.DataSourceDesc { method public long getLength(); method public long getOffset(); method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor(); field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL } 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); Loading @@ -1102,6 +1113,12 @@ package android.media { method public android.media.PlaybackParams setAudioStretchMode(int); } public class UriDataSourceDesc extends android.media.DataSourceDesc { method @Nullable public java.util.List<java.net.HttpCookie> getCookies(); method @Nullable public java.util.Map<java.lang.String,java.lang.String> getHeaders(); method @NonNull public android.net.Uri getUri(); } public static final class VolumeShaper.Configuration.Builder { method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int); } Loading media/apex/java/android/media/CallbackDataSourceDesc.java +7 −74 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; /** * Structure of data source descriptor for sources using callback. Loading @@ -26,12 +26,16 @@ import android.annotation.Nullable; * {@link MediaPlayer2#setNextDataSources} to set data source for playback. * * <p>Users should use {@link Builder} to create {@link CallbackDataSourceDesc}. * * @hide */ @TestApi public class CallbackDataSourceDesc extends DataSourceDesc { private DataSourceCallback mDataSourceCallback; private CallbackDataSourceDesc() { CallbackDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs, DataSourceCallback dataSourceCallback) { super(mediaId, startPositionMs, endPositionMs); mDataSourceCallback = dataSourceCallback; } /** Loading @@ -41,75 +45,4 @@ public class CallbackDataSourceDesc extends DataSourceDesc { public @NonNull DataSourceCallback getDataSourceCallback() { return mDataSourceCallback; } /** * Builder class for {@link CallbackDataSourceDesc} objects. * <p> Here is an example where <code>Builder</code> is used to define the * {@link CallbackDataSourceDesc} to be used by a {@link MediaPlayer2} instance: * * <pre class="prettyprint"> * CallbackDataSourceDesc newDSD = new CallbackDataSourceDesc.Builder() * .setDataSource(media2DataSource) * .setStartPosition(1000) * .setEndPosition(15000) * .build(); * mediaplayer2.setDataSourceDesc(newDSD); * </pre> */ public static class Builder extends BuilderBase<Builder> { private DataSourceCallback mDataSourceCallback; /** * Constructs a new Builder with the defaults. */ public Builder() { super(); } /** * Constructs a new Builder from a given {@link CallbackDataSourceDesc} instance * @param dsd the {@link CallbackDataSourceDesc} object whose data will be reused * in the new Builder. */ public Builder(@Nullable CallbackDataSourceDesc dsd) { super(dsd); if (dsd == null) { return; // use default } mDataSourceCallback = dsd.mDataSourceCallback; } /** * Combines all of the fields that have been set and return a new * {@link CallbackDataSourceDesc} object. <code>IllegalStateException</code> will be * thrown if there is conflict between fields. * * @return a new {@link CallbackDataSourceDesc} object */ public @NonNull CallbackDataSourceDesc build() { if (mDataSourceCallback == null) { throw new IllegalStateException( "DataSourceCallback should not be null"); } CallbackDataSourceDesc dsd = new CallbackDataSourceDesc(); super.build(dsd); dsd.mDataSourceCallback = mDataSourceCallback; return dsd; } /** * Sets the data source (DataSourceCallback) to use. * * @param dscb the DataSourceCallback for the media to play * @return the same Builder instance. * @throws NullPointerException if dscb is null. */ public @NonNull Builder setDataSource(@NonNull DataSourceCallback dscb) { Media2Utils.checkArgument(dscb != null, "data source cannot be null."); mDataSourceCallback = dscb; return this; } } } media/apex/java/android/media/DataSourceDesc.java +237 −23 Original line number Diff line number Diff line Loading @@ -18,15 +18,22 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.os.ParcelFileDescriptor; import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Base class of data source descriptor. * Data source descriptor. * * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and * {@link MediaPlayer2#setNextDataSources} to set data source for playback. * * <p>Users should use subclasses' builder to change {@link DataSourceDesc}. * */ public class DataSourceDesc { // intentionally less than long.MAX_VALUE Loading @@ -45,7 +52,10 @@ public class DataSourceDesc { private long mStartPositionMs = 0; private long mEndPositionMs = POSITION_UNKNOWN; DataSourceDesc() { DataSourceDesc(String mediaId, long startPositionMs, long endPositionMs) { mMediaId = mediaId; mStartPositionMs = startPositionMs; mEndPositionMs = endPositionMs; } /** Loading Loading @@ -97,17 +107,48 @@ public class DataSourceDesc { } /** * Base class for Builders in the subclasses of {@link DataSourceDesc}. * Builder for {@link DataSourceDesc}. * <p> * Here is an example where <code>Builder</code> is used to define the * {@link DataSourceDesc} to be used by a {@link MediaPlayer2} instance: * * <pre class="prettyprint"> * DataSourceDesc newDSD = new DataSourceDesc.Builder() * .setDataSource(context, uri, headers, cookies) * .setStartPosition(1000) * .setEndPosition(15000) * .build(); * mediaplayer2.setDataSourceDesc(newDSD); * </pre> */ protected static class BuilderBase<T extends BuilderBase> { public static final class Builder { private static final int SOURCE_TYPE_UNKNOWN = 0; private static final int SOURCE_TYPE_URI = 1; private static final int SOURCE_TYPE_FILE = 2; private static final int SOURCE_TYPE_CALLBACK = 3; private int mSourceType = SOURCE_TYPE_UNKNOWN; private String mMediaId; private long mStartPositionMs = 0; private long mEndPositionMs = POSITION_UNKNOWN; // For UriDataSourceDesc private Uri mUri; private Map<String, String> mHeader; private List<HttpCookie> mCookies; // For FileDataSourceDesc private ParcelFileDescriptor mPFD; private long mOffset = 0; private long mLength = FileDataSourceDesc.FD_LENGTH_UNKNOWN; // For CallbackDataSourceDesc private DataSourceCallback mDataSourceCallback; /** * Constructs a new BuilderBase with the defaults. */ BuilderBase() { public Builder() { } /** Loading @@ -115,33 +156,61 @@ public class DataSourceDesc { * @param dsd the {@link DataSourceDesc} object whose data will be reused * in the new BuilderBase. */ BuilderBase(DataSourceDesc dsd) { public Builder(@Nullable DataSourceDesc dsd) { if (dsd == null) { return; } mMediaId = dsd.mMediaId; mStartPositionMs = dsd.mStartPositionMs; mEndPositionMs = dsd.mEndPositionMs; if (dsd instanceof FileDataSourceDesc) { mSourceType = SOURCE_TYPE_FILE; mPFD = ((FileDataSourceDesc) dsd).getParcelFileDescriptor(); mOffset = ((FileDataSourceDesc) dsd).getOffset(); mLength = ((FileDataSourceDesc) dsd).getLength(); } else if (dsd instanceof UriDataSourceDesc) { mSourceType = SOURCE_TYPE_URI; mUri = ((UriDataSourceDesc) dsd).getUri(); mHeader = ((UriDataSourceDesc) dsd).getHeaders(); mCookies = ((UriDataSourceDesc) dsd).getCookies(); } else if (dsd instanceof CallbackDataSourceDesc) { mSourceType = SOURCE_TYPE_CALLBACK; mDataSourceCallback = ((CallbackDataSourceDesc) dsd).getDataSourceCallback(); } else { throw new IllegalStateException("Unknown source type:" + mSourceType); } } /** * Sets all fields that have been set in the {@link DataSourceDesc} object. * <code>IllegalStateException</code> will be thrown if there is conflict between fields. * * @param dsd an instance of subclass of {@link DataSourceDesc} whose data will be set * @return the same instance of subclass of {@link DataSourceDesc} * @return {@link DataSourceDesc} */ void build(@NonNull DataSourceDesc dsd) { Media2Utils.checkArgument(dsd != null, "dsd cannot be null."); @NonNull public DataSourceDesc build() { if (mSourceType == SOURCE_TYPE_UNKNOWN) { throw new IllegalStateException("Source is not set."); } if (mStartPositionMs > mEndPositionMs) { throw new IllegalStateException("Illegal start/end position: " + mStartPositionMs + " : " + mEndPositionMs); } dsd.mMediaId = mMediaId; dsd.mStartPositionMs = mStartPositionMs; dsd.mEndPositionMs = mEndPositionMs; DataSourceDesc desc; if (mSourceType == SOURCE_TYPE_FILE) { desc = new FileDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mPFD, mOffset, mLength); } else if (mSourceType == SOURCE_TYPE_URI) { desc = new UriDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mUri, mHeader, mCookies); } else if (mSourceType == SOURCE_TYPE_CALLBACK) { desc = new CallbackDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mDataSourceCallback); } else { throw new IllegalStateException("Unknown source type:" + mSourceType); } return desc; } /** Loading @@ -150,9 +219,10 @@ public class DataSourceDesc { * @param mediaId the media Id of this data source * @return the same Builder instance. */ public @NonNull T setMediaId(@Nullable String mediaId) { @NonNull public Builder setMediaId(@Nullable String mediaId) { mMediaId = mediaId; return (T) this; return this; } /** Loading @@ -163,12 +233,13 @@ public class DataSourceDesc { * @return the same Builder instance. * */ public @NonNull T setStartPosition(long position) { @NonNull public Builder setStartPosition(long position) { if (position < 0) { position = 0; } mStartPositionMs = position; return (T) this; return this; } /** Loading @@ -179,12 +250,155 @@ public class DataSourceDesc { * @param position the end position in milliseconds at which the playback will end * @return the same Builder instance. */ public @NonNull T setEndPosition(long position) { @NonNull public Builder setEndPosition(long position) { if (position < 0) { position = LONG_MAX_TIME_MS; } mEndPositionMs = position; return (T) this; return this; } /** * Sets the data source as a content Uri. * * @param uri the Content URI of the data you want to play * @return the same Builder instance. * @throws NullPointerException if context or uri is null. */ @NonNull public Builder setDataSource(@NonNull Uri uri) { setSourceType(SOURCE_TYPE_URI); Media2Utils.checkArgument(uri != null, "uri cannot be null"); mUri = uri; return this; } /** * Sets the data source as a content Uri. * * To provide cookies for the subsequent HTTP requests, you can install your own default * cookie handler and use other variants of setDataSource APIs instead. Alternatively, you * can use this API to pass the cookies as a list of HttpCookie. If the app has not * installed a CookieHandler already, {@link MediaPlayer2} will create a CookieManager * and populates its CookieStore with the provided cookies when this data source is passed * to {@link MediaPlayer2}. If the app has installed its own handler already, the handler * is required to be of CookieManager type such that {@link MediaPlayer2} can update the * manager’s CookieStore. * * <p><strong>Note</strong> that the cross domain redirection is allowed by default, * but that can be changed with key/value pairs through the headers parameter with * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to * disallow or allow cross domain redirection. * * @param uri the Content URI of the data you want to play * @param headers the headers to be sent together with the request for the data * The headers must not include cookies. Instead, use the cookies param. * @param cookies the cookies to be sent together with the request * @return the same Builder instance. * @throws NullPointerException if context or uri is null. * @throws IllegalArgumentException if the cookie handler is not of CookieManager type * when cookies are provided. */ @NonNull public Builder setDataSource(@NonNull Uri uri, @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies) { setSourceType(SOURCE_TYPE_URI); Media2Utils.checkArgument(uri != null, "uri cannot be null"); if (cookies != null) { CookieHandler cookieHandler = CookieHandler.getDefault(); if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) { throw new IllegalArgumentException( "The cookie handler has to be of CookieManager type " + "when cookies are provided."); } } mUri = uri; if (headers != null) { mHeader = new HashMap<String, String>(headers); } if (cookies != null) { mCookies = new ArrayList<HttpCookie>(cookies); } return this; } /** * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} * created by this builder is passed to {@link MediaPlayer2} via * {@link MediaPlayer2#setDataSource}, * {@link MediaPlayer2#setNextDataSource} or * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will * close the ParcelFileDescriptor. * * @param pfd the ParcelFileDescriptor for the file to play * @return the same Builder instance. * @throws NullPointerException if pfd is null. */ @NonNull public Builder setDataSource(@NonNull ParcelFileDescriptor pfd) { setSourceType(SOURCE_TYPE_FILE); Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); mPFD = pfd; return this; } /** * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} * created by this builder is passed to {@link MediaPlayer2} via * {@link MediaPlayer2#setDataSource}, * {@link MediaPlayer2#setNextDataSource} or * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will * close the ParcelFileDescriptor. * * Any negative number for offset is treated as 0. * Any negative number for length is treated as maximum length of the data source. * * @param pfd the ParcelFileDescriptor for the file to play * @param offset the offset into the file where the data to be played starts, in bytes * @param length the length in bytes of the data to be played * @return the same Builder instance. * @throws NullPointerException if pfd is null. */ @NonNull public Builder setDataSource( @NonNull ParcelFileDescriptor pfd, long offset, long length) { setSourceType(SOURCE_TYPE_FILE); Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); if (offset < 0) { offset = 0; } if (length < 0) { length = FileDataSourceDesc.FD_LENGTH_UNKNOWN; } mPFD = pfd; mOffset = offset; mLength = length; return this; } /** * Sets the data source (DataSourceCallback) to use. * * @param dscb the DataSourceCallback for the media to play * @return the same Builder instance. * @throws NullPointerException if dscb is null. */ public @NonNull Builder setDataSource(@NonNull DataSourceCallback dscb) { setSourceType(SOURCE_TYPE_CALLBACK); Media2Utils.checkArgument(dscb != null, "data source cannot be null."); mDataSourceCallback = dscb; return this; } private void setSourceType(int type) { if (mSourceType != SOURCE_TYPE_UNKNOWN) { throw new IllegalStateException("Source is already set. type=" + mSourceType); } mSourceType = type; } } } media/apex/java/android/media/FileDataSourceDesc.java +9 −133 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
api/current.txt +12 −45 Original line number Diff line number Diff line Loading @@ -23707,17 +23707,6 @@ package android.media { method public void onTearDown(@NonNull android.media.AudioTrack); } public class CallbackDataSourceDesc extends android.media.DataSourceDesc { method @NonNull public android.media.DataSourceCallback getDataSourceCallback(); } public static class CallbackDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.CallbackDataSourceDesc.Builder> { ctor public CallbackDataSourceDesc.Builder(); ctor public CallbackDataSourceDesc.Builder(@Nullable android.media.CallbackDataSourceDesc); method @NonNull public android.media.CallbackDataSourceDesc build(); method @NonNull public android.media.CallbackDataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback); } public class CamcorderProfile { method public static android.media.CamcorderProfile get(int); method public static android.media.CamcorderProfile get(int, int); Loading Loading @@ -23784,10 +23773,18 @@ package android.media { field public static final long POSITION_UNKNOWN = 576460752303423L; // 0x20c49ba5e353fL } protected static class DataSourceDesc.BuilderBase<T extends android.media.DataSourceDesc.BuilderBase> { method @NonNull public T setEndPosition(long); method @NonNull public T setMediaId(@Nullable String); method @NonNull public T setStartPosition(long); public static final class DataSourceDesc.Builder { ctor public DataSourceDesc.Builder(); ctor public DataSourceDesc.Builder(@Nullable android.media.DataSourceDesc); method @NonNull public android.media.DataSourceDesc build(); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback); method @NonNull public android.media.DataSourceDesc.Builder setEndPosition(long); method @NonNull public android.media.DataSourceDesc.Builder setMediaId(@Nullable String); method @NonNull public android.media.DataSourceDesc.Builder setStartPosition(long); } public final class DeniedByServerException extends android.media.MediaDrmException { Loading Loading @@ -23992,21 +23989,6 @@ package android.media { field public static final int EULER_Z = 2; // 0x2 } public class FileDataSourceDesc extends android.media.DataSourceDesc { method public long getLength(); method public long getOffset(); method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor(); field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL } public static class FileDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.FileDataSourceDesc.Builder> { ctor public FileDataSourceDesc.Builder(); ctor public FileDataSourceDesc.Builder(@Nullable android.media.FileDataSourceDesc); method @NonNull public android.media.FileDataSourceDesc build(); method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); } public abstract class Image implements java.lang.AutoCloseable { method public abstract void close(); method public android.graphics.Rect getCropRect(); Loading Loading @@ -26641,21 +26623,6 @@ package android.media { ctor public UnsupportedSchemeException(String); } public class UriDataSourceDesc extends android.media.DataSourceDesc { method @NonNull public android.content.Context getContext(); method @Nullable public java.util.List<java.net.HttpCookie> getCookies(); method @Nullable public java.util.Map<java.lang.String,java.lang.String> getHeaders(); method @NonNull public android.net.Uri getUri(); } public static class UriDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.UriDataSourceDesc.Builder> { ctor public UriDataSourceDesc.Builder(); ctor public UriDataSourceDesc.Builder(@Nullable android.media.UriDataSourceDesc); method @NonNull public android.media.UriDataSourceDesc build(); method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri); method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>); } public interface VolumeAutomation { method @NonNull public android.media.VolumeShaper createVolumeShaper(@NonNull android.media.VolumeShaper.Configuration); }
api/test-current.txt +17 −0 Original line number Diff line number Diff line Loading @@ -1078,6 +1078,17 @@ package android.media { method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int); } public class CallbackDataSourceDesc extends android.media.DataSourceDesc { method @NonNull public android.media.DataSourceCallback getDataSourceCallback(); } public class FileDataSourceDesc extends android.media.DataSourceDesc { method public long getLength(); method public long getOffset(); method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor(); field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL } 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); Loading @@ -1102,6 +1113,12 @@ package android.media { method public android.media.PlaybackParams setAudioStretchMode(int); } public class UriDataSourceDesc extends android.media.DataSourceDesc { method @Nullable public java.util.List<java.net.HttpCookie> getCookies(); method @Nullable public java.util.Map<java.lang.String,java.lang.String> getHeaders(); method @NonNull public android.net.Uri getUri(); } public static final class VolumeShaper.Configuration.Builder { method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int); } Loading
media/apex/java/android/media/CallbackDataSourceDesc.java +7 −74 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; /** * Structure of data source descriptor for sources using callback. Loading @@ -26,12 +26,16 @@ import android.annotation.Nullable; * {@link MediaPlayer2#setNextDataSources} to set data source for playback. * * <p>Users should use {@link Builder} to create {@link CallbackDataSourceDesc}. * * @hide */ @TestApi public class CallbackDataSourceDesc extends DataSourceDesc { private DataSourceCallback mDataSourceCallback; private CallbackDataSourceDesc() { CallbackDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs, DataSourceCallback dataSourceCallback) { super(mediaId, startPositionMs, endPositionMs); mDataSourceCallback = dataSourceCallback; } /** Loading @@ -41,75 +45,4 @@ public class CallbackDataSourceDesc extends DataSourceDesc { public @NonNull DataSourceCallback getDataSourceCallback() { return mDataSourceCallback; } /** * Builder class for {@link CallbackDataSourceDesc} objects. * <p> Here is an example where <code>Builder</code> is used to define the * {@link CallbackDataSourceDesc} to be used by a {@link MediaPlayer2} instance: * * <pre class="prettyprint"> * CallbackDataSourceDesc newDSD = new CallbackDataSourceDesc.Builder() * .setDataSource(media2DataSource) * .setStartPosition(1000) * .setEndPosition(15000) * .build(); * mediaplayer2.setDataSourceDesc(newDSD); * </pre> */ public static class Builder extends BuilderBase<Builder> { private DataSourceCallback mDataSourceCallback; /** * Constructs a new Builder with the defaults. */ public Builder() { super(); } /** * Constructs a new Builder from a given {@link CallbackDataSourceDesc} instance * @param dsd the {@link CallbackDataSourceDesc} object whose data will be reused * in the new Builder. */ public Builder(@Nullable CallbackDataSourceDesc dsd) { super(dsd); if (dsd == null) { return; // use default } mDataSourceCallback = dsd.mDataSourceCallback; } /** * Combines all of the fields that have been set and return a new * {@link CallbackDataSourceDesc} object. <code>IllegalStateException</code> will be * thrown if there is conflict between fields. * * @return a new {@link CallbackDataSourceDesc} object */ public @NonNull CallbackDataSourceDesc build() { if (mDataSourceCallback == null) { throw new IllegalStateException( "DataSourceCallback should not be null"); } CallbackDataSourceDesc dsd = new CallbackDataSourceDesc(); super.build(dsd); dsd.mDataSourceCallback = mDataSourceCallback; return dsd; } /** * Sets the data source (DataSourceCallback) to use. * * @param dscb the DataSourceCallback for the media to play * @return the same Builder instance. * @throws NullPointerException if dscb is null. */ public @NonNull Builder setDataSource(@NonNull DataSourceCallback dscb) { Media2Utils.checkArgument(dscb != null, "data source cannot be null."); mDataSourceCallback = dscb; return this; } } }
media/apex/java/android/media/DataSourceDesc.java +237 −23 Original line number Diff line number Diff line Loading @@ -18,15 +18,22 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.os.ParcelFileDescriptor; import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Base class of data source descriptor. * Data source descriptor. * * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and * {@link MediaPlayer2#setNextDataSources} to set data source for playback. * * <p>Users should use subclasses' builder to change {@link DataSourceDesc}. * */ public class DataSourceDesc { // intentionally less than long.MAX_VALUE Loading @@ -45,7 +52,10 @@ public class DataSourceDesc { private long mStartPositionMs = 0; private long mEndPositionMs = POSITION_UNKNOWN; DataSourceDesc() { DataSourceDesc(String mediaId, long startPositionMs, long endPositionMs) { mMediaId = mediaId; mStartPositionMs = startPositionMs; mEndPositionMs = endPositionMs; } /** Loading Loading @@ -97,17 +107,48 @@ public class DataSourceDesc { } /** * Base class for Builders in the subclasses of {@link DataSourceDesc}. * Builder for {@link DataSourceDesc}. * <p> * Here is an example where <code>Builder</code> is used to define the * {@link DataSourceDesc} to be used by a {@link MediaPlayer2} instance: * * <pre class="prettyprint"> * DataSourceDesc newDSD = new DataSourceDesc.Builder() * .setDataSource(context, uri, headers, cookies) * .setStartPosition(1000) * .setEndPosition(15000) * .build(); * mediaplayer2.setDataSourceDesc(newDSD); * </pre> */ protected static class BuilderBase<T extends BuilderBase> { public static final class Builder { private static final int SOURCE_TYPE_UNKNOWN = 0; private static final int SOURCE_TYPE_URI = 1; private static final int SOURCE_TYPE_FILE = 2; private static final int SOURCE_TYPE_CALLBACK = 3; private int mSourceType = SOURCE_TYPE_UNKNOWN; private String mMediaId; private long mStartPositionMs = 0; private long mEndPositionMs = POSITION_UNKNOWN; // For UriDataSourceDesc private Uri mUri; private Map<String, String> mHeader; private List<HttpCookie> mCookies; // For FileDataSourceDesc private ParcelFileDescriptor mPFD; private long mOffset = 0; private long mLength = FileDataSourceDesc.FD_LENGTH_UNKNOWN; // For CallbackDataSourceDesc private DataSourceCallback mDataSourceCallback; /** * Constructs a new BuilderBase with the defaults. */ BuilderBase() { public Builder() { } /** Loading @@ -115,33 +156,61 @@ public class DataSourceDesc { * @param dsd the {@link DataSourceDesc} object whose data will be reused * in the new BuilderBase. */ BuilderBase(DataSourceDesc dsd) { public Builder(@Nullable DataSourceDesc dsd) { if (dsd == null) { return; } mMediaId = dsd.mMediaId; mStartPositionMs = dsd.mStartPositionMs; mEndPositionMs = dsd.mEndPositionMs; if (dsd instanceof FileDataSourceDesc) { mSourceType = SOURCE_TYPE_FILE; mPFD = ((FileDataSourceDesc) dsd).getParcelFileDescriptor(); mOffset = ((FileDataSourceDesc) dsd).getOffset(); mLength = ((FileDataSourceDesc) dsd).getLength(); } else if (dsd instanceof UriDataSourceDesc) { mSourceType = SOURCE_TYPE_URI; mUri = ((UriDataSourceDesc) dsd).getUri(); mHeader = ((UriDataSourceDesc) dsd).getHeaders(); mCookies = ((UriDataSourceDesc) dsd).getCookies(); } else if (dsd instanceof CallbackDataSourceDesc) { mSourceType = SOURCE_TYPE_CALLBACK; mDataSourceCallback = ((CallbackDataSourceDesc) dsd).getDataSourceCallback(); } else { throw new IllegalStateException("Unknown source type:" + mSourceType); } } /** * Sets all fields that have been set in the {@link DataSourceDesc} object. * <code>IllegalStateException</code> will be thrown if there is conflict between fields. * * @param dsd an instance of subclass of {@link DataSourceDesc} whose data will be set * @return the same instance of subclass of {@link DataSourceDesc} * @return {@link DataSourceDesc} */ void build(@NonNull DataSourceDesc dsd) { Media2Utils.checkArgument(dsd != null, "dsd cannot be null."); @NonNull public DataSourceDesc build() { if (mSourceType == SOURCE_TYPE_UNKNOWN) { throw new IllegalStateException("Source is not set."); } if (mStartPositionMs > mEndPositionMs) { throw new IllegalStateException("Illegal start/end position: " + mStartPositionMs + " : " + mEndPositionMs); } dsd.mMediaId = mMediaId; dsd.mStartPositionMs = mStartPositionMs; dsd.mEndPositionMs = mEndPositionMs; DataSourceDesc desc; if (mSourceType == SOURCE_TYPE_FILE) { desc = new FileDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mPFD, mOffset, mLength); } else if (mSourceType == SOURCE_TYPE_URI) { desc = new UriDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mUri, mHeader, mCookies); } else if (mSourceType == SOURCE_TYPE_CALLBACK) { desc = new CallbackDataSourceDesc( mMediaId, mStartPositionMs, mEndPositionMs, mDataSourceCallback); } else { throw new IllegalStateException("Unknown source type:" + mSourceType); } return desc; } /** Loading @@ -150,9 +219,10 @@ public class DataSourceDesc { * @param mediaId the media Id of this data source * @return the same Builder instance. */ public @NonNull T setMediaId(@Nullable String mediaId) { @NonNull public Builder setMediaId(@Nullable String mediaId) { mMediaId = mediaId; return (T) this; return this; } /** Loading @@ -163,12 +233,13 @@ public class DataSourceDesc { * @return the same Builder instance. * */ public @NonNull T setStartPosition(long position) { @NonNull public Builder setStartPosition(long position) { if (position < 0) { position = 0; } mStartPositionMs = position; return (T) this; return this; } /** Loading @@ -179,12 +250,155 @@ public class DataSourceDesc { * @param position the end position in milliseconds at which the playback will end * @return the same Builder instance. */ public @NonNull T setEndPosition(long position) { @NonNull public Builder setEndPosition(long position) { if (position < 0) { position = LONG_MAX_TIME_MS; } mEndPositionMs = position; return (T) this; return this; } /** * Sets the data source as a content Uri. * * @param uri the Content URI of the data you want to play * @return the same Builder instance. * @throws NullPointerException if context or uri is null. */ @NonNull public Builder setDataSource(@NonNull Uri uri) { setSourceType(SOURCE_TYPE_URI); Media2Utils.checkArgument(uri != null, "uri cannot be null"); mUri = uri; return this; } /** * Sets the data source as a content Uri. * * To provide cookies for the subsequent HTTP requests, you can install your own default * cookie handler and use other variants of setDataSource APIs instead. Alternatively, you * can use this API to pass the cookies as a list of HttpCookie. If the app has not * installed a CookieHandler already, {@link MediaPlayer2} will create a CookieManager * and populates its CookieStore with the provided cookies when this data source is passed * to {@link MediaPlayer2}. If the app has installed its own handler already, the handler * is required to be of CookieManager type such that {@link MediaPlayer2} can update the * manager’s CookieStore. * * <p><strong>Note</strong> that the cross domain redirection is allowed by default, * but that can be changed with key/value pairs through the headers parameter with * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to * disallow or allow cross domain redirection. * * @param uri the Content URI of the data you want to play * @param headers the headers to be sent together with the request for the data * The headers must not include cookies. Instead, use the cookies param. * @param cookies the cookies to be sent together with the request * @return the same Builder instance. * @throws NullPointerException if context or uri is null. * @throws IllegalArgumentException if the cookie handler is not of CookieManager type * when cookies are provided. */ @NonNull public Builder setDataSource(@NonNull Uri uri, @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies) { setSourceType(SOURCE_TYPE_URI); Media2Utils.checkArgument(uri != null, "uri cannot be null"); if (cookies != null) { CookieHandler cookieHandler = CookieHandler.getDefault(); if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) { throw new IllegalArgumentException( "The cookie handler has to be of CookieManager type " + "when cookies are provided."); } } mUri = uri; if (headers != null) { mHeader = new HashMap<String, String>(headers); } if (cookies != null) { mCookies = new ArrayList<HttpCookie>(cookies); } return this; } /** * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} * created by this builder is passed to {@link MediaPlayer2} via * {@link MediaPlayer2#setDataSource}, * {@link MediaPlayer2#setNextDataSource} or * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will * close the ParcelFileDescriptor. * * @param pfd the ParcelFileDescriptor for the file to play * @return the same Builder instance. * @throws NullPointerException if pfd is null. */ @NonNull public Builder setDataSource(@NonNull ParcelFileDescriptor pfd) { setSourceType(SOURCE_TYPE_FILE); Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); mPFD = pfd; return this; } /** * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} * created by this builder is passed to {@link MediaPlayer2} via * {@link MediaPlayer2#setDataSource}, * {@link MediaPlayer2#setNextDataSource} or * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will * close the ParcelFileDescriptor. * * Any negative number for offset is treated as 0. * Any negative number for length is treated as maximum length of the data source. * * @param pfd the ParcelFileDescriptor for the file to play * @param offset the offset into the file where the data to be played starts, in bytes * @param length the length in bytes of the data to be played * @return the same Builder instance. * @throws NullPointerException if pfd is null. */ @NonNull public Builder setDataSource( @NonNull ParcelFileDescriptor pfd, long offset, long length) { setSourceType(SOURCE_TYPE_FILE); Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); if (offset < 0) { offset = 0; } if (length < 0) { length = FileDataSourceDesc.FD_LENGTH_UNKNOWN; } mPFD = pfd; mOffset = offset; mLength = length; return this; } /** * Sets the data source (DataSourceCallback) to use. * * @param dscb the DataSourceCallback for the media to play * @return the same Builder instance. * @throws NullPointerException if dscb is null. */ public @NonNull Builder setDataSource(@NonNull DataSourceCallback dscb) { setSourceType(SOURCE_TYPE_CALLBACK); Media2Utils.checkArgument(dscb != null, "data source cannot be null."); mDataSourceCallback = dscb; return this; } private void setSourceType(int type) { if (mSourceType != SOURCE_TYPE_UNKNOWN) { throw new IllegalStateException("Source is already set. type=" + mSourceType); } mSourceType = type; } } }
media/apex/java/android/media/FileDataSourceDesc.java +9 −133 File changed.Preview size limit exceeded, changes collapsed. Show changes