MediaSync: add OnErrorListener.
Bug: 19666434
Change-Id: I34983d6101cc0f93ee74bdcec5d272808842a5c2
diff --git a/api/current.txt b/api/current.txt
index fee81f5c..1e0138c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16392,10 +16392,13 @@
method public final void release();
method public void setAudioTrack(android.media.AudioTrack);
method public void setCallback(android.media.MediaSync.Callback, android.os.Handler);
+ method public void setOnErrorListener(android.media.MediaSync.OnErrorListener, android.os.Handler);
method public void setPlaybackRate(float, int);
method public void setPlaybackSettings(android.media.PlaybackSettings);
method public void setSurface(android.view.Surface);
method public void setSyncSettings(android.media.SyncSettings);
+ field public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1; // 0x1
+ field public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2; // 0x2
field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
@@ -16406,6 +16409,10 @@
method public abstract void onReturnAudioBuffer(android.media.MediaSync, java.nio.ByteBuffer, int);
}
+ public static abstract interface MediaSync.OnErrorListener {
+ method public abstract void onError(android.media.MediaSync, int, int);
+ }
+
public class MediaSyncEvent {
method public static android.media.MediaSyncEvent createEvent(int) throws java.lang.IllegalArgumentException;
method public int getAudioSessionId();
@@ -16429,6 +16436,14 @@
method public abstract void onAudioDeviceConnection();
}
+ public abstract interface OnAudioRecordRoutingListener {
+ method public abstract void onAudioRecordRouting(android.media.AudioRecord);
+ }
+
+ public abstract interface OnAudioTrackRoutingListener {
+ method public abstract void onAudioTrackRouting(android.media.AudioTrack);
+ }
+
public final class PlaybackSettings {
ctor public PlaybackSettings();
method public android.media.PlaybackSettings allowDefaults();
@@ -16447,14 +16462,6 @@
field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1
}
- public abstract interface OnAudioRecordRoutingListener {
- method public abstract void onAudioRecordRouting(android.media.AudioRecord);
- }
-
- public abstract interface OnAudioTrackRoutingListener {
- method public abstract void onAudioTrackRouting(android.media.AudioTrack);
- }
-
public final class Rating implements android.os.Parcelable {
method public int describeContents();
method public float getPercentRating();
diff --git a/api/system-current.txt b/api/system-current.txt
index 137bb19..7911fd0 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -17608,10 +17608,13 @@
method public final void release();
method public void setAudioTrack(android.media.AudioTrack);
method public void setCallback(android.media.MediaSync.Callback, android.os.Handler);
+ method public void setOnErrorListener(android.media.MediaSync.OnErrorListener, android.os.Handler);
method public void setPlaybackRate(float, int);
method public void setPlaybackSettings(android.media.PlaybackSettings);
method public void setSurface(android.view.Surface);
method public void setSyncSettings(android.media.SyncSettings);
+ field public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1; // 0x1
+ field public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2; // 0x2
field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
@@ -17622,6 +17625,10 @@
method public abstract void onReturnAudioBuffer(android.media.MediaSync, java.nio.ByteBuffer, int);
}
+ public static abstract interface MediaSync.OnErrorListener {
+ method public abstract void onError(android.media.MediaSync, int, int);
+ }
+
public class MediaSyncEvent {
method public static android.media.MediaSyncEvent createEvent(int) throws java.lang.IllegalArgumentException;
method public int getAudioSessionId();
@@ -17645,6 +17652,14 @@
method public abstract void onAudioDeviceConnection();
}
+ public abstract interface OnAudioRecordRoutingListener {
+ method public abstract void onAudioRecordRouting(android.media.AudioRecord);
+ }
+
+ public abstract interface OnAudioTrackRoutingListener {
+ method public abstract void onAudioTrackRouting(android.media.AudioTrack);
+ }
+
public final class PlaybackSettings {
ctor public PlaybackSettings();
method public android.media.PlaybackSettings allowDefaults();
@@ -17663,14 +17678,6 @@
field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1
}
- public abstract interface OnAudioRecordRoutingListener {
- method public abstract void onAudioRecordRouting(android.media.AudioRecord);
- }
-
- public abstract interface OnAudioTrackRoutingListener {
- method public abstract void onAudioTrackRouting(android.media.AudioTrack);
- }
-
public final class Rating implements android.os.Parcelable {
method public int describeContents();
method public float getPercentRating();
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index 3b4f8e5..55c65f6 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -129,6 +129,37 @@
@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 @@
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 @@
}
/**
+ * 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.