From 2f7511fd065aa121287da3d4b5b8bea3e528b0bc Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Mon, 28 Nov 2016 15:40:27 -0800 Subject: [PATCH] Stream types are for volume control Deprecate methods where stream types are not used for volume control operations. Add a warning in the logs about the use of stream types to encourage migration to audio attributes. Since STREAM_ACCESSIBILITY is added in O for the volume of a11y audio, throw an exception when trying to use it for playback. Test: make offline-sdk-docs Bug: 30955183 Change-Id: I7fcf79f1de68f217a9b19561aa1325ade169dfcf --- api/current.txt | 6 ++--- api/system-current.txt | 6 ++--- api/test-current.txt | 6 ++--- core/java/android/app/Notification.java | 2 ++ media/java/android/media/AsyncPlayer.java | 2 ++ media/java/android/media/AudioTrack.java | 12 ++++++++-- media/java/android/media/MediaPlayer.java | 12 ++++++---- media/java/android/media/PlayerBase.java | 24 +++++++++++++++++++ media/java/android/media/Ringtone.java | 1 + media/java/android/media/RingtoneManager.java | 4 +++- media/java/android/media/SoundPool.java | 2 ++ 11 files changed, 60 insertions(+), 17 deletions(-) diff --git a/api/current.txt b/api/current.txt index 8f7e305dfe199..b7538eea9c07e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -20164,8 +20164,8 @@ package android.media { } public class AudioTrack implements android.media.AudioRouting { - ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; - ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; + ctor public deprecated AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; + ctor public deprecated AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler); @@ -21453,7 +21453,7 @@ package android.media { method public void selectTrack(int) throws java.lang.IllegalStateException; method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException; method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; - method public void setAudioStreamType(int); + method public deprecated void setAudioStreamType(int); method public void setAuxEffectSendLevel(float); method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; diff --git a/api/system-current.txt b/api/system-current.txt index 6a57e4888f76c..795a7592efe95 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -21729,8 +21729,8 @@ package android.media { } public class AudioTrack implements android.media.AudioRouting { - ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; - ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; + ctor public deprecated AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; + ctor public deprecated AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler); @@ -23018,7 +23018,7 @@ package android.media { method public void selectTrack(int) throws java.lang.IllegalStateException; method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException; method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; - method public void setAudioStreamType(int); + method public deprecated void setAudioStreamType(int); method public void setAuxEffectSendLevel(float); method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; diff --git a/api/test-current.txt b/api/test-current.txt index 004350dd2eb20..0a9951c1de6f9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -20248,8 +20248,8 @@ package android.media { } public class AudioTrack implements android.media.AudioRouting { - ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; - ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; + ctor public deprecated AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException; + ctor public deprecated AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException; ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler); @@ -21537,7 +21537,7 @@ package android.media { method public void selectTrack(int) throws java.lang.IllegalStateException; method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException; method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; - method public void setAudioStreamType(int); + method public deprecated void setAudioStreamType(int); method public void setAuxEffectSendLevel(float); method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 1fd082f4683e6..c1e20726dff80 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -37,6 +37,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.AudioManager; +import android.media.PlayerBase; import android.media.session.MediaSession; import android.net.Uri; import android.os.BadParcelableException; @@ -2821,6 +2822,7 @@ public class Notification implements Parcelable */ @Deprecated public Builder setSound(Uri sound, int streamType) { + PlayerBase.deprecateStreamTypeForPlayback(streamType, "Notification", "setSound()"); mN.sound = sound; mN.audioStreamType = streamType; return this; diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java index dd5f6bafd9758..c1a178a2bf834 100644 --- a/media/java/android/media/AsyncPlayer.java +++ b/media/java/android/media/AsyncPlayer.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.NonNull; import android.content.Context; +import android.media.PlayerBase; import android.net.Uri; import android.os.PowerManager; import android.os.SystemClock; @@ -163,6 +164,7 @@ public class AsyncPlayer { * @deprecated use {@link #play(Context, Uri, boolean, AudioAttributes)} instead */ public void play(Context context, Uri uri, boolean looping, int stream) { + PlayerBase.deprecateStreamTypeForPlayback(stream, "AsyncPlayer", "play()"); if (context == null || uri == null) { return; } diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 43fb4b9d87a2c..16b331560d2aa 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -359,6 +359,9 @@ public class AudioTrack extends PlayerBase * for an AudioTrack instance in streaming mode. * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM} * @throws java.lang.IllegalArgumentException + * @deprecated use {@link Builder} or + * {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the + * {@link AudioAttributes} instead of the stream type which is only for volume control. */ public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode) @@ -414,6 +417,9 @@ public class AudioTrack extends PlayerBase * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM} * @param sessionId Id of audio session the AudioTrack must be attached to * @throws java.lang.IllegalArgumentException + * @deprecated use {@link Builder} or + * {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the + * {@link AudioAttributes} instead of the stream type which is only for volume control. */ public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId) @@ -429,6 +435,7 @@ public class AudioTrack extends PlayerBase .build(), bufferSizeInBytes, mode, sessionId); + deprecateStreamTypeForPlayback(streamType, "AudioTrack", "AudioTrack()"); } /** @@ -1044,11 +1051,12 @@ public class AudioTrack extends PlayerBase } /** - * Returns the type of audio stream this AudioTrack is configured for. + * Returns the volume stream type of this AudioTrack. * Compare the result against {@link AudioManager#STREAM_VOICE_CALL}, * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING}, * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM}, - * {@link AudioManager#STREAM_NOTIFICATION}, or {@link AudioManager#STREAM_DTMF}. + * {@link AudioManager#STREAM_NOTIFICATION}, {@link AudioManager#STREAM_DTMF} or + * {@link AudioManager#STREAM_ACCESSIBILITY}. */ public int getStreamType() { return mStreamType; diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 36ad90b6026cd..52f4dd30c658b 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -124,7 +124,7 @@ import java.lang.ref.WeakReference; * is called. It is a programming error to invoke methods such * as {@link #getCurrentPosition()}, * {@link #getDuration()}, {@link #getVideoHeight()}, - * {@link #getVideoWidth()}, {@link #setAudioStreamType(int)}, + * {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)}, * {@link #setLooping(boolean)}, * {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()}, * {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or @@ -407,7 +407,7 @@ import java.lang.ref.WeakReference; * Error}

* This method must be called in idle state as the audio session ID must be known before * calling setDataSource. Calling it does not change the object state.

- * setAudioStreamType

+ * setAudioStreamType (deprecated)

* {Idle, Initialized, Stopped, Prepared, Started, Paused, * PlaybackCompleted}

* {Error}

@@ -819,7 +819,7 @@ public class MediaPlayer extends PlayerBase * to free the resources. If not released, too many MediaPlayer instances will * result in an exception.

*

Note that since {@link #prepare()} is called automatically in this method, - * you cannot change the audio stream type (see {@link #setAudioStreamType(int)}), audio + * you cannot change the audio * session ID (see {@link #setAudioSessionId(int)}) or audio attributes * (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.

* @@ -838,7 +838,7 @@ public class MediaPlayer extends PlayerBase * to free the resources. If not released, too many MediaPlayer instances will * result in an exception.

*

Note that since {@link #prepare()} is called automatically in this method, - * you cannot change the audio stream type (see {@link #setAudioStreamType(int)}), audio + * you cannot change the audio * session ID (see {@link #setAudioSessionId(int)}) or audio attributes * (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.

* @@ -901,7 +901,7 @@ public class MediaPlayer extends PlayerBase * to free the resources. If not released, too many MediaPlayer instances will * result in an exception.

*

Note that since {@link #prepare()} is called automatically in this method, - * you cannot change the audio stream type (see {@link #setAudioStreamType(int)}), audio + * you cannot change the audio * session ID (see {@link #setAudioSessionId(int)}) or audio attributes * (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.

* @@ -1746,9 +1746,11 @@ public class MediaPlayer extends PlayerBase * thereafter. * * @param streamtype the audio stream type + * @deprecated use {@link #setAudioAttributes(AudioAttributes)} * @see android.media.AudioManager */ public void setAudioStreamType(int streamtype) { + deprecateStreamTypeForPlayback(streamtype, "MediaPlayer", "setAudioStreamType()"); baseUpdateAudioAttributes( new AudioAttributes.Builder().setInternalLegacyStreamType(streamtype).build()); _setAudioStreamType(streamtype); diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index 690a553849e32..42f6b830126d0 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -236,4 +236,28 @@ public abstract class PlayerBase { */ abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume); abstract int playerSetAuxEffectSendLevel(boolean muting, float level); + + //===================================================================== + // Utilities + + /** + * Use to generate warning or exception in legacy code paths that allowed passing stream types + * to qualify audio playback. + * @param streamType the stream type to check + * @throws IllegalArgumentException + */ + public static void deprecateStreamTypeForPlayback(int streamType, String className, + String opName) throws IllegalArgumentException { + // STREAM_ACCESSIBILITY was introduced at the same time the use of stream types + // for audio playback was deprecated, so it is not allowed at all to qualify a playback + // use case + if (streamType == AudioManager.STREAM_ACCESSIBILITY) { + throw new IllegalArgumentException("Use of STREAM_ACCESSIBILITY is reserved for " + + "volume control"); + } + Log.e(className, "Use of stream types is deprecated for operations other than " + + "volume control."); + Log.e(className, "See the documentation of " + opName + " for what to use instead with " + + "android.media.AudioAttributes to qualify your playback use case"); + } } diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index 77677124d8dc5..209ec42dfb0be 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -103,6 +103,7 @@ public class Ringtone { */ @Deprecated public void setStreamType(int streamType) { + PlayerBase.deprecateStreamTypeForPlayback(streamType, "Ringtone", "setStreamType()"); setAudioAttributes(new AudioAttributes.Builder() .setInternalLegacyStreamType(streamType) .build()); diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 3cb01de7513dd..de9f0202a44c0 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -297,7 +297,7 @@ public class RingtoneManager { } /** - * Infers the playback stream type based on what type of ringtones this + * Infers the volume stream type based on what type of ringtones this * manager is returning. * * @return The stream type. @@ -616,6 +616,7 @@ public class RingtoneManager { return getRingtone(context, ringtoneUri, -1); } + //FIXME bypass the notion of stream types within the class /** * Returns a {@link Ringtone} for a given sound URI on the given stream * type. Normally, if you change the stream type on the returned @@ -630,6 +631,7 @@ public class RingtoneManager { try { final Ringtone r = new Ringtone(context, true); if (streamType >= 0) { + //FIXME deprecated call r.setStreamType(streamType); } r.setUri(ringtoneUri); diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index b429e22135bef..838767ce137e5 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -24,6 +24,7 @@ import android.app.ActivityThread; import android.app.AppOpsManager; import android.content.Context; import android.content.res.AssetFileDescriptor; +import android.media.PlayerBase; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -146,6 +147,7 @@ public class SoundPool extends PlayerBase { public SoundPool(int maxStreams, int streamType, int srcQuality) { this(maxStreams, new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build()); + PlayerBase.deprecateStreamTypeForPlayback(streamType, "SoundPool", "SoundPool()"); } private SoundPool(int maxStreams, AudioAttributes attributes) {