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:
Jean-Michel Trivi
2014-08-13 15:59:47 +00:00
committed by Android Git Automerger
7 changed files with 98 additions and 36 deletions

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {