summaryrefslogtreecommitdiff
path: root/android/media
diff options
context:
space:
mode:
authorJustin Klaassen <justinklaassen@google.com>2018-01-03 13:39:41 -0500
committerJustin Klaassen <justinklaassen@google.com>2018-01-03 13:39:41 -0500
commit98fe7819c6d14f4f464a5cac047f9e82dee5da58 (patch)
treea6b8b93eb21e205b27590ab5e2a1fb9efe27f892 /android/media
parent4217cf85c20565a3446a662a7f07f26137b26b7f (diff)
downloadandroid-28-98fe7819c6d14f4f464a5cac047f9e82dee5da58.tar.gz
Import Android SDK Platform P [4524038]
/google/data/ro/projects/android/fetch_artifact \ --bid 4524038 \ --target sdk_phone_armv7-win_sdk \ sdk-repo-linux-sources-4524038.zip AndroidVersion.ApiLevel has been modified to appear as 28 Change-Id: Ic193bf1cf0cae78d4f2bfb4fbddfe42025c5c3c2
Diffstat (limited to 'android/media')
-rw-r--r--android/media/AudioAttributes.java7
-rw-r--r--android/media/AudioDeviceInfo.java62
-rw-r--r--android/media/AudioManager.java105
-rw-r--r--android/media/AudioRecord.java55
-rw-r--r--android/media/AudioTrack.java55
-rw-r--r--android/media/MediaDrm.java4
-rw-r--r--android/media/MediaMetadata.java47
-rw-r--r--android/media/MediaMetadataRetriever.java25
-rw-r--r--android/media/MediaPlayer.java33
-rw-r--r--android/media/NativeRoutingEventHandlerDelegate.java51
-rw-r--r--android/media/session/PlaybackState.java3
-rw-r--r--android/media/tv/TvContract.java8
12 files changed, 287 insertions, 168 deletions
diff --git a/android/media/AudioAttributes.java b/android/media/AudioAttributes.java
index 7afe267f..e0289f0b 100644
--- a/android/media/AudioAttributes.java
+++ b/android/media/AudioAttributes.java
@@ -741,7 +741,7 @@ public final class AudioAttributes implements Parcelable {
/**
* @hide
* Same as {@link #setCapturePreset(int)} but authorizes the use of HOTWORD,
- * REMOTE_SUBMIX and RADIO_TUNER.
+ * REMOTE_SUBMIX, RADIO_TUNER, VOICE_DOWNLINK, VOICE_UPLINK and VOICE_CALL.
* @param preset
* @return the same Builder instance.
*/
@@ -749,7 +749,10 @@ public final class AudioAttributes implements Parcelable {
public Builder setInternalCapturePreset(int preset) {
if ((preset == MediaRecorder.AudioSource.HOTWORD)
|| (preset == MediaRecorder.AudioSource.REMOTE_SUBMIX)
- || (preset == MediaRecorder.AudioSource.RADIO_TUNER)) {
+ || (preset == MediaRecorder.AudioSource.RADIO_TUNER)
+ || (preset == MediaRecorder.AudioSource.VOICE_DOWNLINK)
+ || (preset == MediaRecorder.AudioSource.VOICE_UPLINK)
+ || (preset == MediaRecorder.AudioSource.VOICE_CALL)) {
mSource = preset;
} else {
setCapturePreset(preset);
diff --git a/android/media/AudioDeviceInfo.java b/android/media/AudioDeviceInfo.java
index 1b89c966..1a97b6ba 100644
--- a/android/media/AudioDeviceInfo.java
+++ b/android/media/AudioDeviceInfo.java
@@ -16,9 +16,12 @@
package android.media;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.util.SparseIntArray;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.TreeSet;
/**
@@ -120,6 +123,57 @@ public final class AudioDeviceInfo {
*/
public static final int TYPE_USB_HEADSET = 22;
+ /** @hide */
+ @IntDef(flag = false, prefix = "TYPE", value = {
+ TYPE_BUILTIN_EARPIECE,
+ TYPE_BUILTIN_SPEAKER,
+ TYPE_WIRED_HEADSET,
+ TYPE_WIRED_HEADPHONES,
+ TYPE_BLUETOOTH_SCO,
+ TYPE_BLUETOOTH_A2DP,
+ TYPE_HDMI,
+ TYPE_DOCK,
+ TYPE_USB_ACCESSORY,
+ TYPE_USB_DEVICE,
+ TYPE_USB_HEADSET,
+ TYPE_TELEPHONY,
+ TYPE_LINE_ANALOG,
+ TYPE_HDMI_ARC,
+ TYPE_LINE_DIGITAL,
+ TYPE_FM,
+ TYPE_AUX_LINE,
+ TYPE_IP }
+ )
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AudioDeviceTypeOut {}
+
+ /** @hide */
+ /*package*/ static boolean isValidAudioDeviceTypeOut(int type) {
+ switch (type) {
+ case TYPE_BUILTIN_EARPIECE:
+ case TYPE_BUILTIN_SPEAKER:
+ case TYPE_WIRED_HEADSET:
+ case TYPE_WIRED_HEADPHONES:
+ case TYPE_BLUETOOTH_SCO:
+ case TYPE_BLUETOOTH_A2DP:
+ case TYPE_HDMI:
+ case TYPE_DOCK:
+ case TYPE_USB_ACCESSORY:
+ case TYPE_USB_DEVICE:
+ case TYPE_USB_HEADSET:
+ case TYPE_TELEPHONY:
+ case TYPE_LINE_ANALOG:
+ case TYPE_HDMI_ARC:
+ case TYPE_LINE_DIGITAL:
+ case TYPE_FM:
+ case TYPE_AUX_LINE:
+ case TYPE_IP:
+ return true;
+ default:
+ return false;
+ }
+ }
+
private final AudioDevicePort mPort;
AudioDeviceInfo(AudioDevicePort port) {
@@ -127,6 +181,14 @@ public final class AudioDeviceInfo {
}
/**
+ * @hide
+ * @return The underlying {@link AudioDevicePort} instance.
+ */
+ public AudioDevicePort getPort() {
+ return mPort;
+ }
+
+ /**
* @return The internal device ID.
*/
public int getId() {
diff --git a/android/media/AudioManager.java b/android/media/AudioManager.java
index 58976ca0..913b5e84 100644
--- a/android/media/AudioManager.java
+++ b/android/media/AudioManager.java
@@ -16,6 +16,7 @@
package android.media;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -52,6 +53,8 @@ import android.util.Log;
import android.util.Slog;
import android.view.KeyEvent;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -911,13 +914,28 @@ public class AudioManager {
/**
* Returns the minimum volume index for a particular stream.
- *
- * @param streamType The stream type whose minimum volume index is returned.
+ * @param streamType The stream type whose minimum volume index is returned. Must be one of
+ * {@link #STREAM_VOICE_CALL}, {@link #STREAM_SYSTEM},
+ * {@link #STREAM_RING}, {@link #STREAM_MUSIC}, {@link #STREAM_ALARM},
+ * {@link #STREAM_NOTIFICATION}, {@link #STREAM_DTMF} or {@link #STREAM_ACCESSIBILITY}.
* @return The minimum valid volume index for the stream.
* @see #getStreamVolume(int)
- * @hide
*/
public int getStreamMinVolume(int streamType) {
+ if (!isPublicStreamType(streamType)) {
+ throw new IllegalArgumentException("Invalid stream type " + streamType);
+ }
+ return getStreamMinVolumeInt(streamType);
+ }
+
+ /**
+ * @hide
+ * Same as {@link #getStreamMinVolume(int)} but without the check on the public stream type.
+ * @param streamType The stream type whose minimum volume index is returned.
+ * @return The minimum valid volume index for the stream.
+ * @see #getStreamVolume(int)
+ */
+ public int getStreamMinVolumeInt(int streamType) {
final IAudioService service = getService();
try {
return service.getStreamMinVolume(streamType);
@@ -943,6 +961,72 @@ public class AudioManager {
}
}
+ // keep in sync with frameworks/av/services/audiopolicy/common/include/Volume.h
+ private static final float VOLUME_MIN_DB = -758.0f;
+
+ /** @hide */
+ @IntDef(flag = false, prefix = "STREAM", value = {
+ STREAM_VOICE_CALL,
+ STREAM_SYSTEM,
+ STREAM_RING,
+ STREAM_MUSIC,
+ STREAM_ALARM,
+ STREAM_NOTIFICATION,
+ STREAM_DTMF,
+ STREAM_ACCESSIBILITY }
+ )
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PublicStreamTypes {}
+
+ /**
+ * Returns the volume in dB (decibel) for the given stream type at the given volume index, on
+ * the given type of audio output device.
+ * @param streamType stream type for which the volume is queried.
+ * @param index the volume index for which the volume is queried. The index value must be
+ * between the minimum and maximum index values for the given stream type (see
+ * {@link #getStreamMinVolume(int)} and {@link #getStreamMaxVolume(int)}).
+ * @param deviceType the type of audio output device for which volume is queried.
+ * @return a volume expressed in dB.
+ * A negative value indicates the audio signal is attenuated. A typical maximum value
+ * at the maximum volume index is 0 dB (no attenuation nor amplification). Muting is
+ * reflected by a value of {@link Float#NEGATIVE_INFINITY}.
+ */
+ public float getStreamVolumeDb(@PublicStreamTypes int streamType, int index,
+ @AudioDeviceInfo.AudioDeviceTypeOut int deviceType) {
+ if (!isPublicStreamType(streamType)) {
+ throw new IllegalArgumentException("Invalid stream type " + streamType);
+ }
+ if (index > getStreamMaxVolume(streamType) || index < getStreamMinVolume(streamType)) {
+ throw new IllegalArgumentException("Invalid stream volume index " + index);
+ }
+ if (!AudioDeviceInfo.isValidAudioDeviceTypeOut(deviceType)) {
+ throw new IllegalArgumentException("Invalid audio output device type " + deviceType);
+ }
+ final float gain = AudioSystem.getStreamVolumeDB(streamType, index,
+ AudioDeviceInfo.convertDeviceTypeToInternalDevice(deviceType));
+ if (gain <= VOLUME_MIN_DB) {
+ return Float.NEGATIVE_INFINITY;
+ } else {
+ return gain;
+ }
+ }
+
+ private static boolean isPublicStreamType(int streamType) {
+ switch (streamType) {
+ case STREAM_VOICE_CALL:
+ case STREAM_SYSTEM:
+ case STREAM_RING:
+ case STREAM_MUSIC:
+ case STREAM_ALARM:
+ case STREAM_NOTIFICATION:
+ case STREAM_DTMF:
+ case STREAM_ACCESSIBILITY:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/**
* Get last audible volume before stream was muted.
*
@@ -1551,6 +1635,21 @@ public class AudioManager {
}
/**
+ * Broadcast Action: microphone muting state changed.
+ *
+ * You <em>cannot</em> receive this through components declared
+ * in manifests, only by explicitly registering for it with
+ * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+ * Context.registerReceiver()}.
+ *
+ * <p>The intent has no extra values, use {@link #isMicrophoneMute} to check whether the
+ * microphone is muted.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MICROPHONE_MUTE_CHANGED =
+ "android.media.action.MICROPHONE_MUTE_CHANGED";
+
+ /**
* Sets the audio mode.
* <p>
* The audio mode encompasses audio routing AND the behavior of
diff --git a/android/media/AudioRecord.java b/android/media/AudioRecord.java
index 0906ba50..27784e96 100644
--- a/android/media/AudioRecord.java
+++ b/android/media/AudioRecord.java
@@ -1516,66 +1516,13 @@ public class AudioRecord implements AudioRouting
}
/**
- * Helper class to handle the forwarding of native events to the appropriate listener
- * (potentially) handled in a different thread
- */
- private class NativeRoutingEventHandlerDelegate {
- private final Handler mHandler;
-
- NativeRoutingEventHandlerDelegate(final AudioRecord record,
- final AudioRouting.OnRoutingChangedListener listener,
- Handler handler) {
- // find the looper for our new event handler
- Looper looper;
- if (handler != null) {
- looper = handler.getLooper();
- } else {
- // no given handler, use the looper the AudioRecord was created in
- looper = mInitializationLooper;
- }
-
- // construct the event handler with this looper
- if (looper != null) {
- // implement the event handler delegate
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- if (record == null) {
- return;
- }
- switch(msg.what) {
- case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
- if (listener != null) {
- listener.onRoutingChanged(record);
- }
- break;
- default:
- loge("Unknown native event type: " + msg.what);
- break;
- }
- }
- };
- } else {
- mHandler = null;
- }
- }
-
- Handler getHandler() {
- return mHandler;
- }
- }
-
- /**
* Sends device list change notification to all listeners.
*/
private void broadcastRoutingChange() {
AudioManager.resetAudioPortGeneration();
synchronized (mRoutingChangeListeners) {
for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
- Handler handler = delegate.getHandler();
- if (handler != null) {
- handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
- }
+ delegate.notifyClient();
}
}
}
diff --git a/android/media/AudioTrack.java b/android/media/AudioTrack.java
index 50145f8a..e535fdf5 100644
--- a/android/media/AudioTrack.java
+++ b/android/media/AudioTrack.java
@@ -2856,10 +2856,7 @@ public class AudioTrack extends PlayerBase
AudioManager.resetAudioPortGeneration();
synchronized (mRoutingChangeListeners) {
for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
- Handler handler = delegate.getHandler();
- if (handler != null) {
- handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
- }
+ delegate.notifyClient();
}
}
}
@@ -2943,56 +2940,6 @@ public class AudioTrack extends PlayerBase
}
}
- /**
- * Helper class to handle the forwarding of native events to the appropriate listener
- * (potentially) handled in a different thread
- */
- private class NativeRoutingEventHandlerDelegate {
- private final Handler mHandler;
-
- NativeRoutingEventHandlerDelegate(final AudioTrack track,
- final AudioRouting.OnRoutingChangedListener listener,
- Handler handler) {
- // find the looper for our new event handler
- Looper looper;
- if (handler != null) {
- looper = handler.getLooper();
- } else {
- // no given handler, use the looper the AudioTrack was created in
- looper = mInitializationLooper;
- }
-
- // construct the event handler with this looper
- if (looper != null) {
- // implement the event handler delegate
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- if (track == null) {
- return;
- }
- switch(msg.what) {
- case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
- if (listener != null) {
- listener.onRoutingChanged(track);
- }
- break;
- default:
- loge("Unknown native event type: " + msg.what);
- break;
- }
- }
- };
- } else {
- mHandler = null;
- }
- }
-
- Handler getHandler() {
- return mHandler;
- }
- }
-
//---------------------------------------------------------
// Methods for IPlayer interface
//--------------------
diff --git a/android/media/MediaDrm.java b/android/media/MediaDrm.java
index 12e5744d..e2f9b47e 100644
--- a/android/media/MediaDrm.java
+++ b/android/media/MediaDrm.java
@@ -977,7 +977,7 @@ public final class MediaDrm {
public static final String PROPERTY_ALGORITHMS = "algorithms";
/** @hide */
- @StringDef({
+ @StringDef(prefix = { "PROPERTY_" }, value = {
PROPERTY_VENDOR,
PROPERTY_VERSION,
PROPERTY_DESCRIPTION,
@@ -1010,7 +1010,7 @@ public final class MediaDrm {
public static final String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
/** @hide */
- @StringDef({
+ @StringDef(prefix = { "PROPERTY_" }, value = {
PROPERTY_DEVICE_UNIQUE_ID,
})
@Retention(RetentionPolicy.SOURCE)
diff --git a/android/media/MediaMetadata.java b/android/media/MediaMetadata.java
index 31eb948d..94d4d556 100644
--- a/android/media/MediaMetadata.java
+++ b/android/media/MediaMetadata.java
@@ -45,34 +45,61 @@ public final class MediaMetadata implements Parcelable {
/**
* @hide
*/
- @StringDef({METADATA_KEY_TITLE, METADATA_KEY_ARTIST, METADATA_KEY_ALBUM, METADATA_KEY_AUTHOR,
- METADATA_KEY_WRITER, METADATA_KEY_COMPOSER, METADATA_KEY_COMPILATION,
- METADATA_KEY_DATE, METADATA_KEY_GENRE, METADATA_KEY_ALBUM_ARTIST, METADATA_KEY_ART_URI,
- METADATA_KEY_ALBUM_ART_URI, METADATA_KEY_DISPLAY_TITLE, METADATA_KEY_DISPLAY_SUBTITLE,
- METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_KEY_DISPLAY_ICON_URI,
- METADATA_KEY_MEDIA_ID, METADATA_KEY_MEDIA_URI})
+ @StringDef(prefix = { "METADATA_KEY_" }, value = {
+ METADATA_KEY_TITLE,
+ METADATA_KEY_ARTIST,
+ METADATA_KEY_ALBUM,
+ METADATA_KEY_AUTHOR,
+ METADATA_KEY_WRITER,
+ METADATA_KEY_COMPOSER,
+ METADATA_KEY_COMPILATION,
+ METADATA_KEY_DATE,
+ METADATA_KEY_GENRE,
+ METADATA_KEY_ALBUM_ARTIST,
+ METADATA_KEY_ART_URI,
+ METADATA_KEY_ALBUM_ART_URI,
+ METADATA_KEY_DISPLAY_TITLE,
+ METADATA_KEY_DISPLAY_SUBTITLE,
+ METADATA_KEY_DISPLAY_DESCRIPTION,
+ METADATA_KEY_DISPLAY_ICON_URI,
+ METADATA_KEY_MEDIA_ID,
+ METADATA_KEY_MEDIA_URI,
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface TextKey {}
/**
* @hide
*/
- @StringDef({METADATA_KEY_DURATION, METADATA_KEY_YEAR, METADATA_KEY_TRACK_NUMBER,
- METADATA_KEY_NUM_TRACKS, METADATA_KEY_DISC_NUMBER, METADATA_KEY_BT_FOLDER_TYPE})
+ @StringDef(prefix = { "METADATA_KEY_" }, value = {
+ METADATA_KEY_DURATION,
+ METADATA_KEY_YEAR,
+ METADATA_KEY_TRACK_NUMBER,
+ METADATA_KEY_NUM_TRACKS,
+ METADATA_KEY_DISC_NUMBER,
+ METADATA_KEY_BT_FOLDER_TYPE,
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface LongKey {}
/**
* @hide
*/
- @StringDef({METADATA_KEY_ART, METADATA_KEY_ALBUM_ART, METADATA_KEY_DISPLAY_ICON})
+ @StringDef(prefix = { "METADATA_KEY_" }, value = {
+ METADATA_KEY_ART,
+ METADATA_KEY_ALBUM_ART,
+ METADATA_KEY_DISPLAY_ICON,
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface BitmapKey {}
/**
* @hide
*/
- @StringDef({METADATA_KEY_USER_RATING, METADATA_KEY_RATING})
+ @StringDef(prefix = { "METADATA_KEY_" }, value = {
+ METADATA_KEY_USER_RATING,
+ METADATA_KEY_RATING,
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface RatingKey {}
diff --git a/android/media/MediaMetadataRetriever.java b/android/media/MediaMetadataRetriever.java
index 0b864018..745eb74d 100644
--- a/android/media/MediaMetadataRetriever.java
+++ b/android/media/MediaMetadataRetriever.java
@@ -226,9 +226,12 @@ public class MediaMetadataRetriever
/**
* Call this method after setDataSource(). This method finds a
* representative frame close to the given time position by considering
- * the given option if possible, and returns it as a bitmap. This is
- * useful for generating a thumbnail for an input data source or just
- * obtain and display a frame at the given time position.
+ * the given option if possible, and returns it as a bitmap.
+ *
+ * <p>If you don't need a full-resolution
+ * frame (for example, because you need a thumbnail image), use
+ * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
+ * method.</p>
*
* @param timeUs The time position where the frame will be retrieved.
* When retrieving the frame at the given time position, there is no
@@ -315,11 +318,15 @@ public class MediaMetadataRetriever
/**
* Call this method after setDataSource(). This method finds a
* representative frame close to the given time position if possible,
- * and returns it as a bitmap. This is useful for generating a thumbnail
- * for an input data source. Call this method if one does not care
+ * and returns it as a bitmap. Call this method if one does not care
* how the frame is found as long as it is close to the given time;
* otherwise, please call {@link #getFrameAtTime(long, int)}.
*
+ * <p>If you don't need a full-resolution
+ * frame (for example, because you need a thumbnail image), use
+ * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
+ * method.</p>
+ *
* @param timeUs The time position where the frame will be retrieved.
* When retrieving the frame at the given time position, there is no
* guarentee that the data source has a frame located at the position.
@@ -339,11 +346,15 @@ public class MediaMetadataRetriever
/**
* Call this method after setDataSource(). This method finds a
* representative frame at any time position if possible,
- * and returns it as a bitmap. This is useful for generating a thumbnail
- * for an input data source. Call this method if one does not
+ * and returns it as a bitmap. Call this method if one does not
* care about where the frame is located; otherwise, please call
* {@link #getFrameAtTime(long)} or {@link #getFrameAtTime(long, int)}
*
+ * <p>If you don't need a full-resolution
+ * frame (for example, because you need a thumbnail image), use
+ * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
+ * method.</p>
+ *
* @return A Bitmap containing a representative video frame, which
* can be null, if such a frame cannot be retrieved.
*
diff --git a/android/media/MediaPlayer.java b/android/media/MediaPlayer.java
index 649c091b..1bc3dfa4 100644
--- a/android/media/MediaPlayer.java
+++ b/android/media/MediaPlayer.java
@@ -1514,7 +1514,8 @@ public class MediaPlayer extends PlayerBase
if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
enableNativeRoutingCallbacksLocked(true);
mRoutingChangeListeners.put(
- listener, new NativeRoutingEventHandlerDelegate(this, listener, handler));
+ listener, new NativeRoutingEventHandlerDelegate(this, listener,
+ handler != null ? handler : mEventHandler));
}
}
}
@@ -1535,36 +1536,6 @@ public class MediaPlayer extends PlayerBase
}
}
- /**
- * Helper class to handle the forwarding of native events to the appropriate listener
- * (potentially) handled in a different thread
- */
- private class NativeRoutingEventHandlerDelegate {
- private MediaPlayer mMediaPlayer;
- private AudioRouting.OnRoutingChangedListener mOnRoutingChangedListener;
- private Handler mHandler;
-
- NativeRoutingEventHandlerDelegate(final MediaPlayer mediaPlayer,
- final AudioRouting.OnRoutingChangedListener listener, Handler handler) {
- mMediaPlayer = mediaPlayer;
- mOnRoutingChangedListener = listener;
- mHandler = handler != null ? handler : mEventHandler;
- }
-
- void notifyClient() {
- if (mHandler != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mOnRoutingChangedListener != null) {
- mOnRoutingChangedListener.onRoutingChanged(mMediaPlayer);
- }
- }
- });
- }
- }
- }
-
private native final boolean native_setOutputDevice(int deviceId);
private native final int native_getRoutedDeviceId();
private native final void native_enableDeviceCallback(boolean enabled);
diff --git a/android/media/NativeRoutingEventHandlerDelegate.java b/android/media/NativeRoutingEventHandlerDelegate.java
new file mode 100644
index 00000000..9a6baf17
--- /dev/null
+++ b/android/media/NativeRoutingEventHandlerDelegate.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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.Handler;
+
+/**
+ * Helper class {@link AudioTrack}, {@link AudioRecord}, {@link MediaPlayer} and {@link MediaRecorder}
+ * to handle the forwarding of native events to the appropriate listener
+ * (potentially) handled in a different thread.
+ * @hide
+ */
+class NativeRoutingEventHandlerDelegate {
+ private AudioRouting mAudioRouting;
+ private AudioRouting.OnRoutingChangedListener mOnRoutingChangedListener;
+ private Handler mHandler;
+
+ NativeRoutingEventHandlerDelegate(final AudioRouting audioRouting,
+ final AudioRouting.OnRoutingChangedListener listener, Handler handler) {
+ mAudioRouting = audioRouting;
+ mOnRoutingChangedListener = listener;
+ mHandler = handler;
+ }
+
+ void notifyClient() {
+ if (mHandler != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mOnRoutingChangedListener != null) {
+ mOnRoutingChangedListener.onRoutingChanged(mAudioRouting);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/android/media/session/PlaybackState.java b/android/media/session/PlaybackState.java
index 8283c8b9..17d16b89 100644
--- a/android/media/session/PlaybackState.java
+++ b/android/media/session/PlaybackState.java
@@ -17,6 +17,7 @@ package android.media.session;
import android.annotation.DrawableRes;
import android.annotation.IntDef;
+import android.annotation.LongDef;
import android.annotation.Nullable;
import android.media.RemoteControlClient;
import android.os.Bundle;
@@ -41,7 +42,7 @@ public final class PlaybackState implements Parcelable {
/**
* @hide
*/
- @IntDef(flag=true, value={ACTION_STOP, ACTION_PAUSE, ACTION_PLAY, ACTION_REWIND,
+ @LongDef(flag=true, value={ACTION_STOP, ACTION_PAUSE, ACTION_PLAY, ACTION_REWIND,
ACTION_SKIP_TO_PREVIOUS, ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_SET_RATING,
ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI, ACTION_PREPARE,
diff --git a/android/media/tv/TvContract.java b/android/media/tv/TvContract.java
index 0f460960..3bbc2c4e 100644
--- a/android/media/tv/TvContract.java
+++ b/android/media/tv/TvContract.java
@@ -1650,7 +1650,7 @@ public final class TvContract {
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
/** @hide */
- @StringDef({
+ @StringDef(prefix = { "TYPE_" }, value = {
TYPE_OTHER,
TYPE_NTSC,
TYPE_PAL,
@@ -1863,7 +1863,7 @@ public final class TvContract {
public static final String TYPE_PREVIEW = "TYPE_PREVIEW";
/** @hide */
- @StringDef({
+ @StringDef(prefix = { "SERVICE_TYPE_" }, value = {
SERVICE_TYPE_OTHER,
SERVICE_TYPE_AUDIO_VIDEO,
SERVICE_TYPE_AUDIO,
@@ -1881,7 +1881,7 @@ public final class TvContract {
public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
/** @hide */
- @StringDef({
+ @StringDef(prefix = { "VIDEO_FORMAT_" }, value = {
VIDEO_FORMAT_240P,
VIDEO_FORMAT_360P,
VIDEO_FORMAT_480I,
@@ -1930,7 +1930,7 @@ public final class TvContract {
public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
/** @hide */
- @StringDef({
+ @StringDef(prefix = { "VIDEO_RESOLUTION_" }, value = {
VIDEO_RESOLUTION_SD,
VIDEO_RESOLUTION_ED,
VIDEO_RESOLUTION_HD,