am f181197f: Merge "Add support for AudioAttributes in android.media.Ringtone" into lmp-dev
* commit 'f181197f9729dbb629c1383efd5faa3f3e0e4558': Add support for AudioAttributes in android.media.Ringtone
This commit is contained in:
@@ -15762,11 +15762,12 @@ package android.media {
|
||||
}
|
||||
|
||||
public class Ringtone {
|
||||
method public int getStreamType();
|
||||
method public deprecated int getStreamType();
|
||||
method public java.lang.String getTitle(android.content.Context);
|
||||
method public boolean isPlaying();
|
||||
method public void play();
|
||||
method public void setStreamType(int);
|
||||
method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
|
||||
method public deprecated void setStreamType(int);
|
||||
method public void stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -279,6 +279,7 @@ public class Notification implements Parcelable
|
||||
*
|
||||
* @deprecated Use {@link #audioAttributes} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int STREAM_DEFAULT = -1;
|
||||
|
||||
/**
|
||||
@@ -288,6 +289,7 @@ public class Notification implements Parcelable
|
||||
*
|
||||
* @deprecated Use {@link #audioAttributes} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public int audioStreamType = STREAM_DEFAULT;
|
||||
|
||||
/**
|
||||
@@ -2193,6 +2195,7 @@ public class Notification implements Parcelable
|
||||
* @deprecated use {@link #setSound(Uri, AudioAttributes)} instead.
|
||||
* @see Notification#sound
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder setSound(Uri sound, int streamType) {
|
||||
mSound = sound;
|
||||
mAudioStreamType = streamType;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.media;
|
||||
|
||||
import android.media.AudioAttributes;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
|
||||
@@ -24,11 +25,11 @@ import android.os.UserHandle;
|
||||
*/
|
||||
interface IRingtonePlayer {
|
||||
/** Used for Ringtone.java playback */
|
||||
void play(IBinder token, in Uri uri, int streamType);
|
||||
void play(IBinder token, in Uri uri, in AudioAttributes aa);
|
||||
void stop(IBinder token);
|
||||
boolean isPlaying(IBinder token);
|
||||
|
||||
/** Used for Notification sound playback. */
|
||||
void playAsync(in Uri uri, in UserHandle user, boolean looping, int streamType);
|
||||
void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa);
|
||||
void stopAsync();
|
||||
}
|
||||
|
||||
@@ -60,7 +60,10 @@ public class Ringtone {
|
||||
private Uri mUri;
|
||||
private String mTitle;
|
||||
|
||||
private int mStreamType = AudioManager.STREAM_RING;
|
||||
private AudioAttributes mAudioAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.build();
|
||||
|
||||
/** {@hide} */
|
||||
public Ringtone(Context context, boolean allowRemote) {
|
||||
@@ -75,22 +78,40 @@ public class Ringtone {
|
||||
* Sets the stream type where this ringtone will be played.
|
||||
*
|
||||
* @param streamType The stream, see {@link AudioManager}.
|
||||
* @deprecated use {@link #setAudioAttributes(AudioAttributes)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setStreamType(int streamType) {
|
||||
mStreamType = streamType;
|
||||
|
||||
// The stream type has to be set before the media player is prepared.
|
||||
// Re-initialize it.
|
||||
setUri(mUri);
|
||||
setAudioAttributes(new AudioAttributes.Builder()
|
||||
.setInternalLegacyStreamType(streamType)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stream type where this ringtone will be played.
|
||||
*
|
||||
* @return The stream type, see {@link AudioManager}.
|
||||
* @deprecated use of stream types is deprecated, see
|
||||
* {@link #setAudioAttributes(AudioAttributes)}
|
||||
*/
|
||||
@Deprecated
|
||||
public int getStreamType() {
|
||||
return mStreamType;
|
||||
return AudioAttributes.toLegacyStreamType(mAudioAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link AudioAttributes} for this ringtone.
|
||||
* @param attributes the non-null attributes characterizing this ringtone.
|
||||
*/
|
||||
public void setAudioAttributes(AudioAttributes attributes)
|
||||
throws IllegalArgumentException {
|
||||
if (attributes == null) {
|
||||
throw new IllegalArgumentException("Invalid null AudioAttributes for Ringtone");
|
||||
}
|
||||
mAudioAttributes = attributes;
|
||||
// The audio attributes have to be set before the media player is prepared.
|
||||
// Re-initialize it.
|
||||
setUri(mUri);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +199,7 @@ public class Ringtone {
|
||||
mLocalPlayer = new MediaPlayer();
|
||||
try {
|
||||
mLocalPlayer.setDataSource(mContext, mUri);
|
||||
mLocalPlayer.setAudioStreamType(mStreamType);
|
||||
mLocalPlayer.setAudioAttributes(mAudioAttributes);
|
||||
mLocalPlayer.prepare();
|
||||
|
||||
} catch (SecurityException e) {
|
||||
@@ -214,13 +235,14 @@ public class Ringtone {
|
||||
if (mLocalPlayer != null) {
|
||||
// do not play ringtones if stream volume is 0
|
||||
// (typically because ringer mode is silent).
|
||||
if (mAudioManager.getStreamVolume(mStreamType) != 0) {
|
||||
if (mAudioManager.getStreamVolume(
|
||||
AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
|
||||
mLocalPlayer.start();
|
||||
}
|
||||
} else if (mAllowRemote && (mRemotePlayer != null)) {
|
||||
final Uri canonicalUri = mUri.getCanonicalUri();
|
||||
try {
|
||||
mRemotePlayer.play(mRemoteToken, canonicalUri, mStreamType);
|
||||
mRemotePlayer.play(mRemoteToken, canonicalUri, mAudioAttributes);
|
||||
} catch (RemoteException e) {
|
||||
if (!playFallbackRingtone()) {
|
||||
Log.w(TAG, "Problem playing ringtone: " + e);
|
||||
@@ -278,7 +300,8 @@ public class Ringtone {
|
||||
}
|
||||
|
||||
private boolean playFallbackRingtone() {
|
||||
if (mAudioManager.getStreamVolume(mStreamType) != 0) {
|
||||
if (mAudioManager.getStreamVolume(AudioAttributes.toLegacyStreamType(mAudioAttributes))
|
||||
!= 0) {
|
||||
int ringtoneType = RingtoneManager.getDefaultType(mUri);
|
||||
if (ringtoneType == -1 ||
|
||||
RingtoneManager.getActualDefaultRingtoneUri(mContext, ringtoneType) != null) {
|
||||
@@ -295,7 +318,7 @@ public class Ringtone {
|
||||
afd.getStartOffset(),
|
||||
afd.getDeclaredLength());
|
||||
}
|
||||
mLocalPlayer.setAudioStreamType(mStreamType);
|
||||
mLocalPlayer.setAudioAttributes(mAudioAttributes);
|
||||
mLocalPlayer.prepare();
|
||||
mLocalPlayer.start();
|
||||
afd.close();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaPlayer.OnCompletionListener;
|
||||
@@ -45,11 +46,11 @@ public class NotificationPlayer implements OnCompletionListener {
|
||||
Context context;
|
||||
Uri uri;
|
||||
boolean looping;
|
||||
int stream;
|
||||
AudioAttributes attributes;
|
||||
long requestTime;
|
||||
|
||||
public String toString() {
|
||||
return "{ code=" + code + " looping=" + looping + " stream=" + stream
|
||||
return "{ code=" + code + " looping=" + looping + " attributes=" + attributes
|
||||
+ " uri=" + uri + " }";
|
||||
}
|
||||
}
|
||||
@@ -79,7 +80,7 @@ public class NotificationPlayer implements OnCompletionListener {
|
||||
(AudioManager) mCmd.context.getSystemService(Context.AUDIO_SERVICE);
|
||||
try {
|
||||
MediaPlayer player = new MediaPlayer();
|
||||
player.setAudioStreamType(mCmd.stream);
|
||||
player.setAudioAttributes(mCmd.attributes);
|
||||
player.setDataSource(mCmd.context, mCmd.uri);
|
||||
player.setLooping(mCmd.looping);
|
||||
player.prepare();
|
||||
@@ -90,10 +91,12 @@ public class NotificationPlayer implements OnCompletionListener {
|
||||
if (mAudioManagerWithAudioFocus == null) {
|
||||
if (mDebug) Log.d(mTag, "requesting AudioFocus");
|
||||
if (mCmd.looping) {
|
||||
audioManager.requestAudioFocus(null, mCmd.stream,
|
||||
audioManager.requestAudioFocus(null,
|
||||
AudioAttributes.toLegacyStreamType(mCmd.attributes),
|
||||
AudioManager.AUDIOFOCUS_GAIN);
|
||||
} else {
|
||||
audioManager.requestAudioFocus(null, mCmd.stream,
|
||||
audioManager.requestAudioFocus(null,
|
||||
AudioAttributes.toLegacyStreamType(mCmd.attributes),
|
||||
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
|
||||
}
|
||||
mAudioManagerWithAudioFocus = audioManager;
|
||||
@@ -280,7 +283,9 @@ public class NotificationPlayer implements OnCompletionListener {
|
||||
* (see {@link MediaPlayer#setLooping(boolean)})
|
||||
* @param stream the AudioStream to use.
|
||||
* (see {@link MediaPlayer#setAudioStreamType(int)})
|
||||
* @deprecated use {@link #play(Context, Uri, boolean, AudioAttributes)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public void play(Context context, Uri uri, boolean looping, int stream) {
|
||||
Command cmd = new Command();
|
||||
cmd.requestTime = SystemClock.uptimeMillis();
|
||||
@@ -288,7 +293,34 @@ public class NotificationPlayer implements OnCompletionListener {
|
||||
cmd.context = context;
|
||||
cmd.uri = uri;
|
||||
cmd.looping = looping;
|
||||
cmd.stream = stream;
|
||||
cmd.attributes = new AudioAttributes.Builder().setInternalLegacyStreamType(stream).build();
|
||||
synchronized (mCmdQueue) {
|
||||
enqueueLocked(cmd);
|
||||
mState = PLAY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start playing the sound. It will actually start playing at some
|
||||
* point in the future. There are no guarantees about latency here.
|
||||
* Calling this before another audio file is done playing will stop
|
||||
* that one and start the new one.
|
||||
*
|
||||
* @param context Your application's context.
|
||||
* @param uri The URI to play. (see {@link MediaPlayer#setDataSource(Context, Uri)})
|
||||
* @param looping Whether the audio should loop forever.
|
||||
* (see {@link MediaPlayer#setLooping(boolean)})
|
||||
* @param attributes the AudioAttributes to use.
|
||||
* (see {@link MediaPlayer#setAudioAttributes(AudioAttributes)})
|
||||
*/
|
||||
public void play(Context context, Uri uri, boolean looping, AudioAttributes attributes) {
|
||||
Command cmd = new Command();
|
||||
cmd.requestTime = SystemClock.uptimeMillis();
|
||||
cmd.code = PLAY;
|
||||
cmd.context = context;
|
||||
cmd.uri = uri;
|
||||
cmd.looping = looping;
|
||||
cmd.attributes = attributes;
|
||||
synchronized (mCmdQueue) {
|
||||
enqueueLocked(cmd);
|
||||
mState = PLAY;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.IAudioService;
|
||||
import android.media.IRingtonePlayer;
|
||||
import android.media.Ringtone;
|
||||
@@ -71,11 +72,11 @@ public class RingtonePlayer extends SystemUI {
|
||||
private final IBinder mToken;
|
||||
private final Ringtone mRingtone;
|
||||
|
||||
public Client(IBinder token, Uri uri, UserHandle user, int streamType) {
|
||||
public Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa) {
|
||||
mToken = token;
|
||||
|
||||
mRingtone = new Ringtone(getContextForUser(user), false);
|
||||
mRingtone.setStreamType(streamType);
|
||||
mRingtone.setAudioAttributes(aa);
|
||||
mRingtone.setUri(uri);
|
||||
}
|
||||
|
||||
@@ -91,7 +92,7 @@ public class RingtonePlayer extends SystemUI {
|
||||
|
||||
private IRingtonePlayer mCallback = new IRingtonePlayer.Stub() {
|
||||
@Override
|
||||
public void play(IBinder token, Uri uri, int streamType) throws RemoteException {
|
||||
public void play(IBinder token, Uri uri, AudioAttributes aa) throws RemoteException {
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
|
||||
+ Binder.getCallingUid() + ")");
|
||||
@@ -101,7 +102,7 @@ public class RingtonePlayer extends SystemUI {
|
||||
client = mClients.get(token);
|
||||
if (client == null) {
|
||||
final UserHandle user = Binder.getCallingUserHandle();
|
||||
client = new Client(token, uri, user, streamType);
|
||||
client = new Client(token, uri, user, aa);
|
||||
token.linkToDeath(client, 0);
|
||||
mClients.put(token, client);
|
||||
}
|
||||
@@ -137,13 +138,13 @@ public class RingtonePlayer extends SystemUI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playAsync(Uri uri, UserHandle user, boolean looping, int streamType) {
|
||||
public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) {
|
||||
if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
|
||||
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
|
||||
throw new SecurityException("Async playback only available from system UID.");
|
||||
}
|
||||
|
||||
mAsyncPlayer.play(getContextForUser(user), uri, looping, streamType);
|
||||
mAsyncPlayer.play(getContextForUser(user), uri, looping, aa);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1761,26 +1761,27 @@ public class NotificationManagerService extends SystemService {
|
||||
if (hasValidSound) {
|
||||
boolean looping =
|
||||
(notification.flags & Notification.FLAG_INSISTENT) != 0;
|
||||
int audioStreamType;
|
||||
if (notification.audioStreamType >= 0) {
|
||||
audioStreamType = notification.audioStreamType;
|
||||
AudioAttributes audioAttributes;
|
||||
if (notification.audioAttributes != null) {
|
||||
audioAttributes = notification.audioAttributes;
|
||||
} else {
|
||||
audioStreamType = DEFAULT_STREAM_TYPE;
|
||||
audioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
|
||||
}
|
||||
mSoundNotification = record;
|
||||
// do not play notifications if stream volume is 0 (typically because
|
||||
// ringer mode is silent) or if there is a user of exclusive audio focus
|
||||
if ((mAudioManager.getStreamVolume(audioStreamType) != 0)
|
||||
&& !mAudioManager.isAudioFocusExclusive()) {
|
||||
if ((mAudioManager.getStreamVolume(
|
||||
AudioAttributes.toLegacyStreamType(audioAttributes)) != 0)
|
||||
&& !mAudioManager.isAudioFocusExclusive()) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final IRingtonePlayer player =
|
||||
mAudioManager.getRingtonePlayer();
|
||||
if (player != null) {
|
||||
if (DBG) Slog.v(TAG, "Playing sound " + soundUri
|
||||
+ " on stream " + audioStreamType);
|
||||
+ " with attributes " + audioAttributes);
|
||||
player.playAsync(soundUri, record.sbn.getUser(), looping,
|
||||
audioStreamType);
|
||||
audioAttributes);
|
||||
buzzBeepBlinked = true;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
|
||||
Reference in New Issue
Block a user