summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongwon Kang <dwkang@google.com>2019-03-21 21:38:57 -0700
committerDongwon Kang <dwkang@google.com>2019-03-21 22:05:48 -0700
commit77ab98645a941d879fe26021e7820ccdbe523c25 (patch)
tree17fbe8257062f69138e9efe1d70869cf4ea10366
parent8a5b8f7c6406b035349534af6a55b95c986775f2 (diff)
Use ProxyFileDescriptorCallback instead of DataSourceCallback
Test: MediaPlayer2Test Bug: 128461264, Bug: 126701061 Change-Id: Id971c77bf9a3003e2f24b716ad784b5f2f56f55f
-rw-r--r--api/current.txt7
-rw-r--r--api/test-current.txt4
-rw-r--r--media/Android.bp2
-rw-r--r--media/apex/java/android/media/CallbackDataSourceDesc.java48
-rw-r--r--media/apex/java/android/media/DataSourceCallback.java6
-rw-r--r--media/apex/java/android/media/DataSourceDesc.java32
-rw-r--r--media/apex/java/android/media/MediaPlayer2.java35
-rw-r--r--media/apex/java/android/media/ProxyDataSourceCallback.java68
8 files changed, 99 insertions, 103 deletions
diff --git a/api/current.txt b/api/current.txt
index 9f9c7de8c1e7..9190c86f6ed6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23759,12 +23759,6 @@ package android.media {
field public static final int QUALITY_MEDIUM = 1; // 0x1
}
- public abstract class DataSourceCallback implements java.io.Closeable {
- ctor public DataSourceCallback();
- method public abstract long getSize() throws java.io.IOException;
- method public abstract int readAt(long, @NonNull byte[], int, int) throws java.io.IOException;
- }
-
public class DataSourceDesc {
method public long getEndPosition();
method @Nullable public String getMediaId();
@@ -23781,7 +23775,6 @@ package android.media {
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);
diff --git a/api/test-current.txt b/api/test-current.txt
index 16fdc941bb28..79fb6db8d06a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1078,10 +1078,6 @@ 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();
diff --git a/media/Android.bp b/media/Android.bp
index 86dc509501a4..34801813ee87 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -90,7 +90,6 @@ filegroup {
"apex/java/android/media/DataSourceDesc.java",
"apex/java/android/media/UriDataSourceDesc.java",
"apex/java/android/media/FileDataSourceDesc.java",
- "apex/java/android/media/CallbackDataSourceDesc.java",
"apex/java/android/media/Media2Utils.java",
"apex/java/android/media/MediaPlayer2Utils.java",
"apex/java/android/media/MediaPlayer2.java",
@@ -98,6 +97,7 @@ filegroup {
"apex/java/android/media/Media2HTTPConnection.java",
"apex/java/android/media/RoutingDelegate.java",
"apex/java/android/media/BufferingParams.java",
+ "apex/java/android/media/ProxyDataSourceCallback.java",
],
}
diff --git a/media/apex/java/android/media/CallbackDataSourceDesc.java b/media/apex/java/android/media/CallbackDataSourceDesc.java
deleted file mode 100644
index d9db62e99126..000000000000
--- a/media/apex/java/android/media/CallbackDataSourceDesc.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.NonNull;
-import android.annotation.TestApi;
-
-/**
- * Structure of data source descriptor for sources using callback.
- *
- * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and
- * {@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;
-
- CallbackDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs,
- DataSourceCallback dataSourceCallback) {
- super(mediaId, startPositionMs, endPositionMs);
- mDataSourceCallback = dataSourceCallback;
- }
-
- /**
- * Return the DataSourceCallback of this data source.
- * @return the DataSourceCallback of this data source
- */
- public @NonNull DataSourceCallback getDataSourceCallback() {
- return mDataSourceCallback;
- }
-}
diff --git a/media/apex/java/android/media/DataSourceCallback.java b/media/apex/java/android/media/DataSourceCallback.java
index 6515bd6a2c09..c297ecda249c 100644
--- a/media/apex/java/android/media/DataSourceCallback.java
+++ b/media/apex/java/android/media/DataSourceCallback.java
@@ -32,8 +32,12 @@ import java.io.IOException;
* you don't need to do your own synchronization unless you're modifying the
* DataSourceCallback from another thread while it's being used by the framework.</p>
*
+ * @hide
*/
public abstract class DataSourceCallback implements Closeable {
+
+ public static final int END_OF_STREAM = -1;
+
/**
* Called to request data from the given position.
*
@@ -49,7 +53,7 @@ public abstract class DataSourceCallback implements Closeable {
* @param offset the offset within buffer to read the data into.
* @param size the number of bytes to read.
* @throws IOException on fatal errors.
- * @return the number of bytes read, or -1 if end of stream is reached.
+ * @return the number of bytes read, or {@link #END_OF_STREAM} if end of stream is reached.
*/
public abstract int readAt(long position, @NonNull byte[] buffer, int offset, int size)
throws IOException;
diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java
index be80c2255844..d00ff2a70955 100644
--- a/media/apex/java/android/media/DataSourceDesc.java
+++ b/media/apex/java/android/media/DataSourceDesc.java
@@ -125,7 +125,6 @@ public class DataSourceDesc {
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;
@@ -142,9 +141,6 @@ public class DataSourceDesc {
private long mOffset = 0;
private long mLength = FileDataSourceDesc.FD_LENGTH_UNKNOWN;
- // For CallbackDataSourceDesc
- private DataSourceCallback mDataSourceCallback;
-
/**
* Constructs a new BuilderBase with the defaults.
*/
@@ -173,9 +169,6 @@ public class DataSourceDesc {
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);
}
@@ -204,9 +197,6 @@ public class DataSourceDesc {
} 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);
}
@@ -326,7 +316,7 @@ public class DataSourceDesc {
/**
* Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be
- * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc}
+ * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc}
* created by this builder is passed to {@link MediaPlayer2} via
* {@link MediaPlayer2#setDataSource},
* {@link MediaPlayer2#setNextDataSource} or
@@ -347,7 +337,7 @@ public class DataSourceDesc {
/**
* Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be
- * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc}
+ * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc}
* created by this builder is passed to {@link MediaPlayer2} via
* {@link MediaPlayer2#setDataSource},
* {@link MediaPlayer2#setNextDataSource} or
@@ -367,7 +357,9 @@ public class DataSourceDesc {
public Builder setDataSource(
@NonNull ParcelFileDescriptor pfd, long offset, long length) {
setSourceType(SOURCE_TYPE_FILE);
- Media2Utils.checkArgument(pfd != null, "pfd cannot be null.");
+ if (pfd == null) {
+ throw new NullPointerException("pfd cannot be null.");
+ }
if (offset < 0) {
offset = 0;
}
@@ -380,20 +372,6 @@ public class DataSourceDesc {
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);
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 68a46ed5b8b8..21b1167aadb0 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -878,22 +878,27 @@ public class MediaPlayer2 implements AutoCloseable, AudioRouting {
throws IOException {
Media2Utils.checkArgument(dsd != null, "the DataSourceDesc cannot be null");
- if (dsd instanceof CallbackDataSourceDesc) {
- CallbackDataSourceDesc cbDSD = (CallbackDataSourceDesc) dsd;
- handleDataSource(isCurrent,
- srcId,
- cbDSD.getDataSourceCallback(),
- cbDSD.getStartPosition(),
- cbDSD.getEndPosition());
- } else if (dsd instanceof FileDataSourceDesc) {
+ if (dsd instanceof FileDataSourceDesc) {
FileDataSourceDesc fileDSD = (FileDataSourceDesc) dsd;
- handleDataSource(isCurrent,
- srcId,
- fileDSD.getParcelFileDescriptor(),
- fileDSD.getOffset(),
- fileDSD.getLength(),
- fileDSD.getStartPosition(),
- fileDSD.getEndPosition());
+ ParcelFileDescriptor pfd = fileDSD.getParcelFileDescriptor();
+ if (pfd.getStatSize() == -1) {
+ // Underlying pipeline doesn't understand '-1' size. Create a wrapper for
+ // translation.
+ // TODO: Make native code handle '-1' size.
+ handleDataSource(isCurrent,
+ srcId,
+ new ProxyDataSourceCallback(pfd),
+ fileDSD.getStartPosition(),
+ fileDSD.getEndPosition());
+ } else {
+ handleDataSource(isCurrent,
+ srcId,
+ pfd,
+ fileDSD.getOffset(),
+ fileDSD.getLength(),
+ fileDSD.getStartPosition(),
+ fileDSD.getEndPosition());
+ }
} else if (dsd instanceof UriDataSourceDesc) {
UriDataSourceDesc uriDSD = (UriDataSourceDesc) dsd;
handleDataSource(isCurrent,
diff --git a/media/apex/java/android/media/ProxyDataSourceCallback.java b/media/apex/java/android/media/ProxyDataSourceCallback.java
new file mode 100644
index 000000000000..14d3ce87f03d
--- /dev/null
+++ b/media/apex/java/android/media/ProxyDataSourceCallback.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * A DataSourceCallback that is backed by a ParcelFileDescriptor.
+ */
+class ProxyDataSourceCallback extends DataSourceCallback {
+ private static final String TAG = "TestDataSourceCallback";
+
+ ParcelFileDescriptor mPFD;
+ FileDescriptor mFD;
+
+ ProxyDataSourceCallback(ParcelFileDescriptor pfd) throws IOException {
+ mPFD = pfd.dup();
+ mFD = mPFD.getFileDescriptor();
+ }
+
+ @Override
+ public synchronized int readAt(long position, byte[] buffer, int offset, int size)
+ throws IOException {
+ try {
+ Os.lseek(mFD, position, OsConstants.SEEK_SET);
+ int ret = Os.read(mFD, buffer, offset, size);
+ return (ret == 0) ? END_OF_STREAM : ret;
+ } catch (ErrnoException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public synchronized long getSize() throws IOException {
+ return mPFD.getStatSize();
+ }
+
+ @Override
+ public synchronized void close() {
+ try {
+ mPFD.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to close the PFD.", e);
+ }
+ }
+}
+