summaryrefslogtreecommitdiffstats
path: root/media/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'media/java/android')
-rw-r--r--media/java/android/media/AudioFormat.java15
-rw-r--r--media/java/android/media/AudioManager.java14
-rw-r--r--media/java/android/media/AudioTrack.java56
-rw-r--r--media/java/android/media/Image.java29
-rw-r--r--media/java/android/media/ImageReader.java16
-rw-r--r--media/java/android/media/ImageWriter.java74
-rw-r--r--media/java/android/media/MediaCodec.java35
-rw-r--r--media/java/android/media/MediaSync.java78
-rw-r--r--media/java/android/media/PlaybackSettings.java12
-rw-r--r--media/java/android/media/tv/TvContentRating.java15
-rw-r--r--media/java/android/media/tv/TvInputManager.java110
-rw-r--r--media/java/android/media/tv/TvInputService.java11
-rw-r--r--media/java/android/media/tv/TvTrackInfo.java9
13 files changed, 228 insertions, 246 deletions
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index ff6fed2..a7e092f 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -55,16 +55,16 @@ public class AudioFormat {
public static final int ENCODING_DTS_HD = 8;
/** Invalid audio channel configuration */
- /** @deprecated use CHANNEL_INVALID instead */
+ /** @deprecated Use {@link #CHANNEL_INVALID} instead. */
@Deprecated public static final int CHANNEL_CONFIGURATION_INVALID = 0;
/** Default audio channel configuration */
- /** @deprecated use CHANNEL_OUT_DEFAULT or CHANNEL_IN_DEFAULT instead */
+ /** @deprecated Use {@link #CHANNEL_OUT_DEFAULT} or {@link #CHANNEL_IN_DEFAULT} instead. */
@Deprecated public static final int CHANNEL_CONFIGURATION_DEFAULT = 1;
/** Mono audio configuration */
- /** @deprecated use CHANNEL_OUT_MONO or CHANNEL_IN_MONO instead */
+ /** @deprecated Use {@link #CHANNEL_OUT_MONO} or {@link #CHANNEL_IN_MONO} instead. */
@Deprecated public static final int CHANNEL_CONFIGURATION_MONO = 2;
/** Stereo (2 channel) audio configuration */
- /** @deprecated use CHANNEL_OUT_STEREO or CHANNEL_IN_STEREO instead */
+ /** @deprecated Use {@link #CHANNEL_OUT_STEREO} or {@link #CHANNEL_IN_STEREO} instead. */
@Deprecated public static final int CHANNEL_CONFIGURATION_STEREO = 3;
/** Invalid audio channel mask */
@@ -117,12 +117,11 @@ public class AudioFormat {
public static final int CHANNEL_OUT_5POINT1_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY |
CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT);
- // TODO does this need an @deprecated ?
- // different from AUDIO_CHANNEL_OUT_7POINT1
- public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ // different from AUDIO_CHANNEL_OUT_7POINT1 used internally, and not accepted by AudioRecord.
+ /** @deprecated Not the typical 7.1 surround configuration. Use {@link #CHANNEL_OUT_7POINT1_SURROUND} instead. */
+ @Deprecated public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
- /** @hide */
// matches AUDIO_CHANNEL_OUT_7POINT1
public static final int CHANNEL_OUT_7POINT1_SURROUND = (
CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_FRONT_RIGHT |
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index cb70e8b..d851ad7 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3147,6 +3147,20 @@ public class AudioManager {
"android.media.property.OUTPUT_FRAMES_PER_BUFFER";
/**
+ * Used as a key for {@link #getProperty} to determine if the default microphone audio source
+ * supports near-ultrasound frequencies (range of 18 - 21 kHz).
+ */
+ public static final String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND =
+ "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
+
+ /**
+ * Used as a key for {@link #getProperty} to determine if the default speaker audio path
+ * supports near-ultrasound frequencies (range of 18 - 21 kHz).
+ */
+ public static final String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND =
+ "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
+
+ /**
* Returns the value of the property with the specified key.
* @param key One of the strings corresponding to a property key: either
* {@link #PROPERTY_OUTPUT_SAMPLE_RATE} or
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 3577357..6f1fd24 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -491,7 +491,7 @@ public class AudioTrack
session[0] = sessionId;
// native initialization
int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
- mSampleRate, mChannels, mAudioFormat,
+ mSampleRate, mChannels, mChannelIndexMask, mAudioFormat,
mNativeBufferSizeInBytes, mDataLoadMode, session);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing AudioTrack.");
@@ -701,48 +701,6 @@ public class AudioTrack
AudioFormat.CHANNEL_OUT_SIDE_LEFT |
AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
- // Java channel mask definitions below match those
- // in /system/core/include/system/audio.h in the JNI code of AudioTrack.
-
- // internal maximum size for bits parameter, not part of public API
- private static final int AUDIO_CHANNEL_BITS_LOG2 = 30;
-
- // log(2) of maximum number of representations, not part of public API
- private static final int AUDIO_CHANNEL_REPRESENTATION_LOG2 = 2;
-
- // used to create a channel index mask or channel position mask
- // with getChannelMaskFromRepresentationAndBits();
- private static final int CHANNEL_OUT_REPRESENTATION_POSITION = 0;
- private static final int CHANNEL_OUT_REPRESENTATION_INDEX = 2;
-
- /**
- * Return the channel mask from its representation and bits.
- *
- * This creates a channel mask for mChannels which combines a
- * representation field and a bits field. This is for internal
- * communication to native code, not part of the public API.
- *
- * @param representation the type of channel mask,
- * either CHANNEL_OUT_REPRESENTATION_POSITION
- * or CHANNEL_OUT_REPRESENTATION_INDEX
- * @param bits is the channel bits specifying occupancy
- * @return the channel mask
- * @throws java.lang.IllegalArgumentException if representation is not recognized or
- * the bits field is not acceptable for that representation
- */
- private static int getChannelMaskFromRepresentationAndBits(int representation, int bits) {
- switch (representation) {
- case CHANNEL_OUT_REPRESENTATION_POSITION:
- case CHANNEL_OUT_REPRESENTATION_INDEX:
- if ((bits & ~((1 << AUDIO_CHANNEL_BITS_LOG2) - 1)) != 0) {
- throw new IllegalArgumentException("invalid bits " + bits);
- }
- return representation << AUDIO_CHANNEL_BITS_LOG2 | bits;
- default:
- throw new IllegalArgumentException("invalid representation " + representation);
- }
- }
-
// Convenience method for the constructor's parameter checks.
// This is where constructor IllegalArgumentException-s are thrown
// postconditions:
@@ -804,11 +762,6 @@ public class AudioTrack
} else if (mChannelCount != channelIndexCount) {
throw new IllegalArgumentException("Channel count must match");
}
-
- // AudioTrack prefers to use the channel index configuration
- // over the channel position configuration if both are specified.
- mChannels = getChannelMaskFromRepresentationAndBits(
- CHANNEL_OUT_REPRESENTATION_INDEX, mChannelIndexMask);
}
//--------------
@@ -973,8 +926,7 @@ public class AudioTrack
return new PlaybackSettings()
.setSpeed(floatArray[0])
.setPitch(floatArray[1])
- .setAudioFallbackMode(intArray[0])
- .setAudioStretchMode(intArray[1]);
+ .setAudioFallbackMode(intArray[0]);
}
/**
@@ -1397,7 +1349,7 @@ public class AudioTrack
};
intArray = new int[] {
settings.getAudioFallbackMode(),
- settings.getAudioStretchMode(),
+ PlaybackSettings.AUDIO_STRETCH_MODE_DEFAULT,
};
} catch (IllegalStateException e) {
throw new IllegalArgumentException(e);
@@ -2362,7 +2314,7 @@ public class AudioTrack
// AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC
private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
Object /*AudioAttributes*/ attributes,
- int sampleRate, int channelMask, int audioFormat,
+ int sampleRate, int channelMask, int channelIndexMask, int audioFormat,
int buffSizeInBytes, int mode, int[] sessionId);
private native final void native_finalize();
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 75901fd..195c987 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -50,10 +50,25 @@ public abstract class Image implements AutoCloseable {
/**
* @hide
*/
+ protected boolean mIsImageValid = false;
+
+ /**
+ * @hide
+ */
protected Image() {
}
/**
+ * Throw IllegalStateException if the image is invalid (already closed).
+ *
+ * @hide
+ */
+ protected void throwISEIfImageIsInvalid() {
+ if (!mIsImageValid) {
+ throw new IllegalStateException("Image is already closed");
+ }
+ }
+ /**
* Get the format for this image. This format determines the number of
* ByteBuffers needed to represent the image, and the general layout of the
* pixel data in each in ByteBuffer.
@@ -160,7 +175,7 @@ public abstract class Image implements AutoCloseable {
* Set the timestamp associated with this frame.
* <p>
* The timestamp is measured in nanoseconds, and is normally monotonically
- * increasing. However, However, the behavior of the timestamp depends on
+ * increasing. However, the behavior of the timestamp depends on
* the destination of this image. See {@link android.hardware.Camera Camera}
* , {@link android.hardware.camera2.CameraDevice CameraDevice},
* {@link MediaPlayer} and {@link MediaCodec} for more details.
@@ -176,6 +191,7 @@ public abstract class Image implements AutoCloseable {
* @param timestamp The timestamp to be set for this image.
*/
public void setTimestamp(long timestamp) {
+ throwISEIfImageIsInvalid();
return;
}
@@ -187,6 +203,7 @@ public abstract class Image implements AutoCloseable {
* </p>
*/
public boolean isOpaque() {
+ throwISEIfImageIsInvalid();
return false;
}
@@ -199,6 +216,8 @@ public abstract class Image implements AutoCloseable {
* using coordinates in the largest-resolution plane.
*/
public Rect getCropRect() {
+ throwISEIfImageIsInvalid();
+
if (mCropRect == null) {
return new Rect(0, 0, getWidth(), getHeight());
} else {
@@ -213,6 +232,8 @@ public abstract class Image implements AutoCloseable {
* using coordinates in the largest-resolution plane.
*/
public void setCropRect(Rect cropRect) {
+ throwISEIfImageIsInvalid();
+
if (cropRect != null) {
cropRect = new Rect(cropRect); // make a copy
cropRect.intersect(0, 0, getWidth(), getHeight());
@@ -260,6 +281,8 @@ public abstract class Image implements AutoCloseable {
* a new owner.
*/
boolean isAttachable() {
+ throwISEIfImageIsInvalid();
+
return false;
}
@@ -279,6 +302,8 @@ public abstract class Image implements AutoCloseable {
* @return The owner of the Image.
*/
Object getOwner() {
+ throwISEIfImageIsInvalid();
+
return null;
}
@@ -294,6 +319,8 @@ public abstract class Image implements AutoCloseable {
* @return native context associated with this Image.
*/
long getNativeContext() {
+ throwISEIfImageIsInvalid();
+
return 0;
}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index e54525d..6d30208 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -368,7 +368,7 @@ public class ImageReader implements AutoCloseable {
switch (status) {
case ACQUIRE_SUCCESS:
si.createSurfacePlanes();
- si.setImageValid(true);
+ si.mIsImageValid = true;
case ACQUIRE_NO_BUFS:
case ACQUIRE_MAX_IMAGES:
break;
@@ -444,7 +444,7 @@ public class ImageReader implements AutoCloseable {
si.clearSurfacePlanes();
nativeReleaseImage(i);
- si.setImageValid(false);
+ si.mIsImageValid = false;
}
/**
@@ -686,7 +686,6 @@ public class ImageReader implements AutoCloseable {
private class SurfaceImage extends android.media.Image {
public SurfaceImage(int format) {
- mIsImageValid = false;
mFormat = format;
}
@@ -784,16 +783,6 @@ public class ImageReader implements AutoCloseable {
mIsDetached.getAndSet(detached);
}
- private void setImageValid(boolean isValid) {
- mIsImageValid = isValid;
- }
-
- private void throwISEIfImageIsInvalid() {
- if (!mIsImageValid) {
- throw new IllegalStateException("Image is already closed");
- }
- }
-
private void clearSurfacePlanes() {
if (mIsImageValid) {
for (int i = 0; i < mPlanes.length; i++) {
@@ -877,7 +866,6 @@ public class ImageReader implements AutoCloseable {
private long mTimestamp;
private SurfacePlane[] mPlanes;
- private boolean mIsImageValid;
private int mHeight = -1;
private int mWidth = -1;
private int mFormat = ImageFormat.UNKNOWN;
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index c18b463..f805339 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -29,7 +29,6 @@ import java.nio.ByteOrder;
import java.nio.NioUtils;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* <p>
@@ -204,7 +203,7 @@ public class ImageWriter implements AutoCloseable {
WriterSurfaceImage newImage = new WriterSurfaceImage(this);
nativeDequeueInputImage(mNativeContext, newImage);
mDequeuedImages.add(newImage);
- newImage.setImageValid(true);
+ newImage.mIsImageValid = true;
return newImage;
}
@@ -260,7 +259,7 @@ public class ImageWriter implements AutoCloseable {
throw new IllegalArgumentException("image shouldn't be null");
}
boolean ownedByMe = isImageOwnedByMe(image);
- if (ownedByMe && !(((WriterSurfaceImage) image).isImageValid())) {
+ if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
throw new IllegalStateException("Image from ImageWriter is invalid");
}
@@ -312,7 +311,7 @@ public class ImageWriter implements AutoCloseable {
// Do not call close here, as close is essentially cancel image.
WriterSurfaceImage wi = (WriterSurfaceImage) image;
wi.clearSurfacePlanes();
- wi.setImageValid(false);
+ wi.mIsImageValid = false;
}
}
@@ -555,7 +554,7 @@ public class ImageWriter implements AutoCloseable {
WriterSurfaceImage wi = (WriterSurfaceImage) image;
- if (!wi.isImageValid()) {
+ if (!wi.mIsImageValid) {
throw new IllegalStateException("Image is invalid");
}
@@ -568,7 +567,7 @@ public class ImageWriter implements AutoCloseable {
cancelImage(mNativeContext, image);
mDequeuedImages.remove(image);
wi.clearSurfacePlanes();
- wi.setImageValid(false);
+ wi.mIsImageValid = false;
}
private boolean isImageOwnedByMe(Image image) {
@@ -585,7 +584,6 @@ public class ImageWriter implements AutoCloseable {
private static class WriterSurfaceImage extends android.media.Image {
private ImageWriter mOwner;
- private AtomicBoolean mIsImageValid = new AtomicBoolean(false);
// This field is used by native code, do not access or modify.
private long mNativeBuffer;
private int mNativeFenceFd = -1;
@@ -604,9 +602,8 @@ public class ImageWriter implements AutoCloseable {
@Override
public int getFormat() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
+
if (mFormat == -1) {
mFormat = nativeGetFormat();
}
@@ -615,9 +612,7 @@ public class ImageWriter implements AutoCloseable {
@Override
public int getWidth() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
if (mWidth == -1) {
mWidth = nativeGetWidth();
@@ -628,9 +623,7 @@ public class ImageWriter implements AutoCloseable {
@Override
public int getHeight() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
if (mHeight == -1) {
mHeight = nativeGetHeight();
@@ -641,36 +634,28 @@ public class ImageWriter implements AutoCloseable {
@Override
public long getTimestamp() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
return mTimestamp;
}
@Override
public void setTimestamp(long timestamp) {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
mTimestamp = timestamp;
}
@Override
public boolean isOpaque() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
return getFormat() == ImageFormat.PRIVATE;
}
@Override
public Plane[] getPlanes() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
if (mPlanes == null) {
int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat());
@@ -682,9 +667,7 @@ public class ImageWriter implements AutoCloseable {
@Override
boolean isAttachable() {
- if (!mIsImageValid.get()) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
// Don't allow Image to be detached from ImageWriter for now, as no
// detach API is exposed.
return false;
@@ -692,17 +675,21 @@ public class ImageWriter implements AutoCloseable {
@Override
ImageWriter getOwner() {
+ throwISEIfImageIsInvalid();
+
return mOwner;
}
@Override
long getNativeContext() {
+ throwISEIfImageIsInvalid();
+
return mNativeBuffer;
}
@Override
public void close() {
- if (mIsImageValid.get()) {
+ if (mIsImageValid) {
getOwner().abortImage(this);
}
}
@@ -716,16 +703,8 @@ public class ImageWriter implements AutoCloseable {
}
}
- private boolean isImageValid() {
- return mIsImageValid.get();
- }
-
- private void setImageValid(boolean isValid) {
- mIsImageValid.getAndSet(isValid);
- }
-
private void clearSurfacePlanes() {
- if (mIsImageValid.get()) {
+ if (mIsImageValid) {
for (int i = 0; i < mPlanes.length; i++) {
if (mPlanes[i] != null) {
mPlanes[i].clearBuffer();
@@ -756,26 +735,19 @@ public class ImageWriter implements AutoCloseable {
@Override
public int getRowStride() {
- if (WriterSurfaceImage.this.isImageValid() == false) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
return mRowStride;
}
@Override
public int getPixelStride() {
- if (WriterSurfaceImage.this.isImageValid() == false) {
- throw new IllegalStateException("Image is already released");
- }
+ throwISEIfImageIsInvalid();
return mPixelStride;
}
@Override
public ByteBuffer getBuffer() {
- if (WriterSurfaceImage.this.isImageValid() == false) {
- throw new IllegalStateException("Image is already released");
- }
-
+ throwISEIfImageIsInvalid();
return mBuffer;
}
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1f00c7b..d22cfda 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2059,7 +2059,6 @@ final public class MediaCodec {
/** @hide */
public static class MediaImage extends Image {
private final boolean mIsReadOnly;
- private boolean mIsValid;
private final int mWidth;
private final int mHeight;
private final int mFormat;
@@ -2072,36 +2071,42 @@ final public class MediaCodec {
private final static int TYPE_YUV = 1;
+ @Override
public int getFormat() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mFormat;
}
+ @Override
public int getHeight() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mHeight;
}
+ @Override
public int getWidth() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mWidth;
}
+ @Override
public long getTimestamp() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mTimestamp;
}
+ @Override
@NonNull
public Plane[] getPlanes() {
- checkValid();
+ throwISEIfImageIsInvalid();
return Arrays.copyOf(mPlanes, mPlanes.length);
}
+ @Override
public void close() {
- if (mIsValid) {
+ if (mIsImageValid) {
java.nio.NioUtils.freeDirectBuffer(mBuffer);
- mIsValid = false;
+ mIsImageValid = false;
}
}
@@ -2111,6 +2116,7 @@ final public class MediaCodec {
* The crop rectangle specifies the region of valid pixels in the image,
* using coordinates in the largest-resolution plane.
*/
+ @Override
public void setCropRect(@Nullable Rect cropRect) {
if (mIsReadOnly) {
throw new ReadOnlyBufferException();
@@ -2118,11 +2124,6 @@ final public class MediaCodec {
super.setCropRect(cropRect);
}
- private void checkValid() {
- if (!mIsValid) {
- throw new IllegalStateException("Image is already released");
- }
- }
private int readInt(@NonNull ByteBuffer buffer, boolean asLong) {
if (asLong) {
@@ -2137,7 +2138,7 @@ final public class MediaCodec {
long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) {
mFormat = ImageFormat.YUV_420_888;
mTimestamp = timestamp;
- mIsValid = true;
+ mIsImageValid = true;
mIsReadOnly = buffer.isReadOnly();
mBuffer = buffer.duplicate();
@@ -2208,20 +2209,20 @@ final public class MediaCodec {
@Override
public int getRowStride() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mRowInc;
}
@Override
public int getPixelStride() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mColInc;
}
@Override
@NonNull
public ByteBuffer getBuffer() {
- checkValid();
+ throwISEIfImageIsInvalid();
return mData;
}
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index 3b4f8e5..dc6760d 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -49,7 +49,7 @@ import java.util.List;
* sync.setAudioTrack(audioTrack);
* sync.setCallback(new MediaSync.Callback() {
* {@literal @Override}
- * public void onReturnAudioBuffer(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
+ * public void onAudioBufferConsumed(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
* ...
* }
* }, null);
@@ -88,7 +88,7 @@ import java.util.List;
* }
*
* // This is the callback from MediaSync.
- * onReturnAudioBuffer(MediaSync sync, ByteBuffer buffer, int bufferIndex) {
+ * onAudioBufferConsumed(MediaSync sync, ByteBuffer buffer, int bufferIndex) {
* // ...
* audioDecoder.releaseBuffer(bufferIndex, false);
* // ...
@@ -104,7 +104,7 @@ import java.util.List;
* <p>
* For audio, the client needs to set up audio track correctly, e.g., using {@link
* AudioTrack#MODE_STREAM}. The audio buffers are sent to MediaSync directly via {@link
- * #queueAudio}, and are returned to the client via {@link Callback#onReturnAudioBuffer}
+ * #queueAudio}, and are returned to the client via {@link Callback#onAudioBufferConsumed}
* asynchronously. The client should not modify an audio buffer till it's returned.
* <p>
* The client can optionally pre-fill audio/video buffers by setting playback rate to 0.0,
@@ -125,10 +125,41 @@ final public class MediaSync {
* @param audioBuffer The returned audio buffer.
* @param bufferIndex The index associated with the audio buffer
*/
- public abstract void onReturnAudioBuffer(
+ public abstract void onAudioBufferConsumed(
@NonNull MediaSync sync, @NonNull ByteBuffer audioBuffer, int bufferIndex);
}
+ /** Audio track failed.
+ * @see android.media.MediaSync.OnErrorListener
+ */
+ public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1;
+
+ /** The surface failed to handle video buffers.
+ * @see android.media.MediaSync.OnErrorListener
+ */
+ public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2;
+
+ /**
+ * Interface definition of a callback to be invoked when there
+ * has been an error during an asynchronous operation (other errors
+ * will throw exceptions at method call time).
+ */
+ public interface OnErrorListener {
+ /**
+ * Called to indicate an error.
+ *
+ * @param sync The MediaSync the error pertains to
+ * @param what The type of error that has occurred:
+ * <ul>
+ * <li>{@link #MEDIASYNC_ERROR_AUDIOTRACK_FAIL}
+ * <li>{@link #MEDIASYNC_ERROR_SURFACE_FAIL}
+ * </ul>
+ * @param extra an extra code, specific to the error. Typically
+ * implementation dependent.
+ */
+ void onError(@NonNull MediaSync sync, int what, int extra);
+ }
+
private static final String TAG = "MediaSync";
private static final int EVENT_CALLBACK = 1;
@@ -155,6 +186,10 @@ final public class MediaSync {
private Handler mCallbackHandler = null;
private MediaSync.Callback mCallback = null;
+ private final Object mOnErrorListenerLock = new Object();
+ private Handler mOnErrorListenerHandler = null;
+ private MediaSync.OnErrorListener mOnErrorListener = null;
+
private Thread mAudioThread = null;
// Created on mAudioThread when mAudioThread is started. When used on user thread, they should
// be guarded by checking mAudioThread.
@@ -235,6 +270,39 @@ final public class MediaSync {
}
/**
+ * Sets an asynchronous callback for error events.
+ * <p>
+ * This method can be called multiple times to update a previously set listener. If the
+ * handler is changed, undelivered notifications scheduled for the old handler may be dropped.
+ * <p>
+ * <b>Do not call this inside callback.</b>
+ *
+ * @param listener The callback that will run. Use {@code null} to stop receiving callbacks.
+ * @param handler The Handler that will run the callback. Use {@code null} to use MediaSync's
+ * internal handler if it exists.
+ */
+ public void setOnErrorListener(@Nullable /* MediaSync. */ OnErrorListener listener,
+ @Nullable Handler handler) {
+ synchronized(mOnErrorListenerLock) {
+ if (handler != null) {
+ mOnErrorListenerHandler = handler;
+ } else {
+ Looper looper;
+ if ((looper = Looper.myLooper()) == null) {
+ looper = Looper.getMainLooper();
+ }
+ if (looper == null) {
+ mOnErrorListenerHandler = null;
+ } else {
+ mOnErrorListenerHandler = new Handler(looper);
+ }
+ }
+
+ mOnErrorListener = listener;
+ }
+ }
+
+ /**
* Sets the output surface for MediaSync.
* <p>
* Currently, this is only supported in the Initialized state.
@@ -614,7 +682,7 @@ final public class MediaSync {
return;
}
if (mCallback != null) {
- mCallback.onReturnAudioBuffer(sync, audioBuffer.mByteBuffer,
+ mCallback.onAudioBufferConsumed(sync, audioBuffer.mByteBuffer,
audioBuffer.mBufferIndex);
}
}
diff --git a/media/java/android/media/PlaybackSettings.java b/media/java/android/media/PlaybackSettings.java
index ceb6bb1..b2e1033 100644
--- a/media/java/android/media/PlaybackSettings.java
+++ b/media/java/android/media/PlaybackSettings.java
@@ -38,14 +38,6 @@ import android.annotation.IntDef;
* Return {@link java.lang.IllegalArgumentException} from
* <code>AudioTrack.setPlaybackSettings(PlaybackSettings)</code>.</li>
* </ul>
- * <p> <strong>audio stretch mode:</strong> select
- * timestretch handling.
- * <ul>
- * <li> {@link PlaybackSettings#AUDIO_STRETCH_MODE_DEFAULT}:
- * System will determine best selection. </li>
- * <li> {@link PlaybackSettings#AUDIO_STRETCH_MODE_VOICE}:
- * Content is primarily voice.</li>
- * </ul>
* <p> <strong>pitch:</strong> increases or decreases the tonal frequency of the audio content.
* It is expressed as a multiplicative factor, where normal pitch is 1.0f.
* <p> <strong>speed:</strong> increases or decreases the time to
@@ -84,7 +76,9 @@ public final class PlaybackSettings {
)
@Retention(RetentionPolicy.SOURCE)
public @interface AudioStretchMode {}
+ /** @hide */
public static final int AUDIO_STRETCH_MODE_DEFAULT = 0;
+ /** @hide */
public static final int AUDIO_STRETCH_MODE_VOICE = 1;
// flags to indicate which settings are actually set
@@ -136,6 +130,7 @@ public final class PlaybackSettings {
}
/**
+ * @hide
* Sets the audio stretch mode.
* @param audioStretchMode
* @return this <code>PlaybackSettings</code> instance.
@@ -147,6 +142,7 @@ public final class PlaybackSettings {
}
/**
+ * @hide
* Retrieves the audio stretch mode.
* @return audio stretch mode
* @throws IllegalStateException if the audio stretch mode is not set.
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 754facd..966e41a 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -16,9 +16,12 @@
package android.media.tv;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.text.TextUtils;
+import com.android.internal.util.Preconditions;
+
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -693,6 +696,12 @@ public final class TvContentRating {
private final int mHashCode;
/**
+ * Rating constant denoting unrated content.
+ */
+ public static final TvContentRating UNRATED = new TvContentRating("com.android.tv", "",
+ "UNRATED", null);
+
+ /**
* Creates a {@code TvContentRating} object with predefined content rating strings.
*
* @param domain The domain string. For example, "com.android.tv".
@@ -833,10 +842,8 @@ public final class TvContentRating {
* @hide
*/
@SystemApi
- public final boolean contains(TvContentRating rating) {
- if (rating == null) {
- throw new IllegalArgumentException("rating cannot be null");
- }
+ public final boolean contains(@NonNull TvContentRating rating) {
+ Preconditions.checkNotNull(rating);
if (!rating.getMainRating().equals(mRating)) {
return false;
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 0f265de..601fa45 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -40,6 +40,8 @@ import android.view.KeyEvent;
import android.view.Surface;
import android.view.View;
+import com.android.internal.util.Preconditions;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
@@ -934,9 +936,7 @@ public final class TvInputManager {
*/
@Nullable
public TvInputInfo getTvInputInfo(@NonNull String inputId) {
- if (inputId == null) {
- throw new IllegalArgumentException("inputId cannot be null");
- }
+ Preconditions.checkNotNull(inputId);
try {
return mService.getTvInputInfo(inputId, mUserId);
} catch (RemoteException e) {
@@ -958,9 +958,7 @@ public final class TvInputManager {
* @throws IllegalArgumentException if the argument is {@code null}.
*/
public int getInputState(@NonNull String inputId) {
- if (inputId == null) {
- throw new IllegalArgumentException("inputId cannot be null");
- }
+ Preconditions.checkNotNull(inputId);
synchronized (mLock) {
Integer state = mStateMap.get(inputId);
if (state == null) {
@@ -976,15 +974,10 @@ public final class TvInputManager {
*
* @param callback A callback used to monitor status of the TV inputs.
* @param handler A {@link Handler} that the status change will be delivered to.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
*/
public void registerCallback(@NonNull TvInputCallback callback, @NonNull Handler handler) {
- if (callback == null) {
- throw new IllegalArgumentException("callback cannot be null");
- }
- if (handler == null) {
- throw new IllegalArgumentException("handler cannot be null");
- }
+ Preconditions.checkNotNull(callback);
+ Preconditions.checkNotNull(handler);
synchronized (mLock) {
mCallbackRecords.add(new TvInputCallbackRecord(callback, handler));
}
@@ -994,12 +987,9 @@ public final class TvInputManager {
* Unregisters the existing {@link TvInputCallback}.
*
* @param callback The existing callback to remove.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
*/
public void unregisterCallback(@NonNull final TvInputCallback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("callback cannot be null");
- }
+ Preconditions.checkNotNull(callback);
synchronized (mLock) {
for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator();
it.hasNext(); ) {
@@ -1049,9 +1039,7 @@ public final class TvInputManager {
* @return {@code true} if the given TV content rating is blocked, {@code false} otherwise.
*/
public boolean isRatingBlocked(@NonNull TvContentRating rating) {
- if (rating == null) {
- throw new IllegalArgumentException("rating cannot be null");
- }
+ Preconditions.checkNotNull(rating);
try {
return mService.isRatingBlocked(rating.flattenToString(), mUserId);
} catch (RemoteException e) {
@@ -1087,10 +1075,8 @@ public final class TvInputManager {
* @hide
*/
@SystemApi
- public void addBlockedRating(TvContentRating rating) {
- if (rating == null) {
- throw new IllegalArgumentException("rating cannot be null");
- }
+ public void addBlockedRating(@NonNull TvContentRating rating) {
+ Preconditions.checkNotNull(rating);
try {
mService.addBlockedRating(rating.flattenToString(), mUserId);
} catch (RemoteException e) {
@@ -1107,10 +1093,8 @@ public final class TvInputManager {
* @hide
*/
@SystemApi
- public void removeBlockedRating(TvContentRating rating) {
- if (rating == null) {
- throw new IllegalArgumentException("rating cannot be null");
- }
+ public void removeBlockedRating(@NonNull TvContentRating rating) {
+ Preconditions.checkNotNull(rating);
try {
mService.removeBlockedRating(rating.flattenToString(), mUserId);
} catch (RemoteException e) {
@@ -1140,21 +1124,14 @@ public final class TvInputManager {
* @param inputId The id of the TV input.
* @param callback A callback used to receive the created session.
* @param handler A {@link Handler} that the session creation will be delivered to.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
* @hide
*/
@SystemApi
- public void createSession(String inputId, final SessionCallback callback,
- Handler handler) {
- if (inputId == null) {
- throw new IllegalArgumentException("id cannot be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback cannot be null");
- }
- if (handler == null) {
- throw new IllegalArgumentException("handler cannot be null");
- }
+ public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback,
+ @NonNull Handler handler) {
+ Preconditions.checkNotNull(inputId);
+ Preconditions.checkNotNull(callback);
+ Preconditions.checkNotNull(handler);
SessionCallbackRecord record = new SessionCallbackRecord(callback, handler);
synchronized (mSessionCallbackRecordMap) {
int seq = mNextSeq++;
@@ -1436,7 +1413,6 @@ public final class TvInputManager {
* Tunes to a given channel.
*
* @param channelUri The URI of a channel.
- * @throws IllegalArgumentException if the argument is {@code null}.
*/
public void tune(Uri channelUri) {
tune(channelUri, null);
@@ -1447,14 +1423,11 @@ public final class TvInputManager {
*
* @param channelUri The URI of a channel.
* @param params A set of extra parameters which might be handled with this tune event.
- * @throws IllegalArgumentException if {@code channelUri} is {@code null}.
* @hide
*/
@SystemApi
- public void tune(Uri channelUri, Bundle params) {
- if (channelUri == null) {
- throw new IllegalArgumentException("channelUri cannot be null");
- }
+ public void tune(@NonNull Uri channelUri, Bundle params) {
+ Preconditions.checkNotNull(channelUri);
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
@@ -1790,16 +1763,11 @@ public final class TvInputManager {
*
* @param view A view playing TV.
* @param frame A position of the overlay view.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
* @throws IllegalStateException if {@code view} is not attached to a window.
*/
- void createOverlayView(View view, Rect frame) {
- if (view == null) {
- throw new IllegalArgumentException("view cannot be null");
- }
- if (frame == null) {
- throw new IllegalArgumentException("frame cannot be null");
- }
+ void createOverlayView(@NonNull View view, @NonNull Rect frame) {
+ Preconditions.checkNotNull(view);
+ Preconditions.checkNotNull(frame);
if (view.getWindowToken() == null) {
throw new IllegalStateException("view must be attached to a window");
}
@@ -1818,12 +1786,9 @@ public final class TvInputManager {
* Relayouts the current overlay view.
*
* @param frame A new position of the overlay view.
- * @throws IllegalArgumentException if the arguments is {@code null}.
*/
- void relayoutOverlayView(Rect frame) {
- if (frame == null) {
- throw new IllegalArgumentException("frame cannot be null");
- }
+ void relayoutOverlayView(@NonNull Rect frame) {
+ Preconditions.checkNotNull(frame);
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
@@ -1853,14 +1818,12 @@ public final class TvInputManager {
/**
* Requests to unblock content blocked by parental controls.
*/
- void requestUnblockContent(TvContentRating unblockedRating) {
+ void requestUnblockContent(@NonNull TvContentRating unblockedRating) {
+ Preconditions.checkNotNull(unblockedRating);
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
}
- if (unblockedRating == null) {
- throw new IllegalArgumentException("unblockedRating cannot be null");
- }
try {
mService.requestUnblockContent(mToken, unblockedRating.flattenToString(), mUserId);
} catch (RemoteException e) {
@@ -1871,25 +1834,22 @@ public final class TvInputManager {
/**
* Dispatches an input event to this session.
*
- * @param event An {@link InputEvent} to dispatch.
+ * @param event An {@link InputEvent} to dispatch. Cannot be {@code null}.
* @param token A token used to identify the input event later in the callback.
- * @param callback A callback used to receive the dispatch result.
- * @param handler A {@link Handler} that the dispatch result will be delivered to.
+ * @param callback A callback used to receive the dispatch result. Cannot be {@code null}.
+ * @param handler A {@link Handler} that the dispatch result will be delivered to. Cannot be
+ * {@code null}.
* @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns
* {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns
* {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will
* be invoked later.
- * @throws IllegalArgumentException if any of the necessary arguments is {@code null}.
* @hide
*/
- public int dispatchInputEvent(InputEvent event, Object token,
- FinishedInputEventCallback callback, Handler handler) {
- if (event == null) {
- throw new IllegalArgumentException("event cannot be null");
- }
- if (callback != null && handler == null) {
- throw new IllegalArgumentException("handler cannot be null");
- }
+ public int dispatchInputEvent(@NonNull InputEvent event, Object token,
+ @NonNull FinishedInputEventCallback callback, @NonNull Handler handler) {
+ Preconditions.checkNotNull(event);
+ Preconditions.checkNotNull(callback);
+ Preconditions.checkNotNull(handler);
synchronized (mHandler) {
if (mChannel == null) {
return DISPATCH_NOT_HANDLED;
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 4258534..5156ae8 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -51,6 +51,7 @@ import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.HashSet;
@@ -313,10 +314,8 @@ public abstract class TvInputService extends Service {
* @hide
*/
@SystemApi
- public void notifySessionEvent(final String eventType, final Bundle eventArgs) {
- if (eventType == null) {
- throw new IllegalArgumentException("eventType cannot be null");
- }
+ public void notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs) {
+ Preconditions.checkNotNull(eventType);
executeOrPostRunnable(new Runnable() {
@Override
public void run() {
@@ -546,9 +545,7 @@ public abstract class TvInputService extends Service {
* @see TvInputManager
*/
public void notifyContentBlocked(@NonNull final TvContentRating rating) {
- if (rating == null) {
- throw new IllegalArgumentException("rating cannot be null");
- }
+ Preconditions.checkNotNull(rating);
executeOrPostRunnable(new Runnable() {
@Override
public void run() {
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 6eedeb4..2c956e9 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -16,10 +16,13 @@
package android.media.tv;
+import android.annotation.NonNull;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.Preconditions;
+
/**
* Encapsulates the format of tracks played in {@link TvInputService}.
*/
@@ -245,15 +248,13 @@ public final class TvTrackInfo implements Parcelable {
* @param id The ID of the track that uniquely identifies the current track among all the
* other tracks in the same TV program.
*/
- public Builder(int type, String id) {
+ public Builder(int type, @NonNull String id) {
if (type != TYPE_AUDIO
&& type != TYPE_VIDEO
&& type != TYPE_SUBTITLE) {
throw new IllegalArgumentException("Unknown type: " + type);
}
- if (id == null) {
- throw new IllegalArgumentException("id cannot be null");
- }
+ Preconditions.checkNotNull(id);
mType = type;
mId = id;
}