Switch Session APIs over to AudioAttributes

The session apis were using audioStream in several places. This
updates them to use AudioAttributes instead.

bug:16403289
Change-Id: Ic4da9ca5fbea2536e80c71503bd9a9bf7f346997
This commit is contained in:
RoboErik
2014-07-21 12:44:53 -07:00
committed by Erik Pasternak
parent 4bd39ec448
commit 9db9bf7034
8 changed files with 103 additions and 68 deletions

View File

@@ -16596,7 +16596,7 @@ package android.media.session {
}
public static final class MediaController.VolumeInfo {
method public int getAudioStream();
method public android.media.AudioAttributes getAudioAttributes();
method public int getCurrentVolume();
method public int getMaxVolume();
method public int getVolumeControl();
@@ -16621,7 +16621,7 @@ package android.media.session {
method public void setMediaRouter(android.media.routing.MediaRouter);
method public void setMetadata(android.media.MediaMetadata);
method public void setPlaybackState(android.media.session.PlaybackState);
method public void setPlaybackToLocal(int);
method public void setPlaybackToLocal(android.media.AudioAttributes);
method public void setPlaybackToRemote(android.media.VolumeProvider);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2

View File

@@ -0,0 +1,18 @@
/* Copyright 2014, 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;
parcelable AudioAttributes;

View File

@@ -2220,7 +2220,9 @@ public class MediaRouter {
}
} else {
// We only know how to handle local and remote, fall back to local if not remote.
session.setPlaybackToLocal(mPlaybackStream);
AudioAttributes.Builder bob = new AudioAttributes.Builder();
bob.setLegacyStreamType(mPlaybackStream);
session.setPlaybackToLocal(bob.build());
mSvp = null;
}
}

View File

@@ -16,6 +16,7 @@
package android.media.session;
import android.content.ComponentName;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
import android.media.routing.IMediaRouter;
import android.media.session.ISessionController;
@@ -42,6 +43,7 @@ interface ISession {
void setRatingType(int type);
// These commands relate to volume handling
void configureVolumeHandling(int type, int arg1, int arg2);
void setPlaybackToLocal(in AudioAttributes attributes);
void setPlaybackToRemote(int control, int max);
void setCurrentVolume(int currentVolume);
}

View File

@@ -18,6 +18,7 @@ package android.media.session;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.Rating;
@@ -206,7 +207,7 @@ public final class MediaController {
public @Nullable VolumeInfo getVolumeInfo() {
try {
ParcelableVolumeInfo result = mSessionBinder.getVolumeAttributes();
return new VolumeInfo(result.volumeType, result.audioStream, result.controlType,
return new VolumeInfo(result.volumeType, result.audioAttrs, result.controlType,
result.maxVolume, result.currentVolume);
} catch (RemoteException e) {
@@ -216,8 +217,8 @@ public final class MediaController {
}
/**
* Set the volume of the stream or output this session is playing on. The
* command will be ignored if it does not support
* Set the volume of the output this session is playing on. The command will
* be ignored if it does not support
* {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
* {@link AudioManager} may be used to affect the handling.
*
@@ -234,8 +235,8 @@ public final class MediaController {
}
/**
* Adjust the volume of the stream or output this session is playing on. The
* direction must be one of {@link AudioManager#ADJUST_LOWER},
* Adjust the volume of the output this session is playing on. The direction
* must be one of {@link AudioManager#ADJUST_LOWER},
* {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}.
* The command will be ignored if the session does not support
* {@link VolumeProvider#VOLUME_CONTROL_RELATIVE} or
@@ -570,17 +571,17 @@ public final class MediaController {
*/
public static final class VolumeInfo {
private final int mVolumeType;
private final int mAudioStream;
private final int mVolumeControl;
private final int mMaxVolume;
private final int mCurrentVolume;
private final AudioAttributes mAudioAttrs;
/**
* @hide
*/
public VolumeInfo(int type, int stream, int control, int max, int current) {
public VolumeInfo(int type, AudioAttributes attrs, int control, int max, int current) {
mVolumeType = type;
mAudioStream = stream;
mAudioAttrs = attrs;
mVolumeControl = control;
mMaxVolume = max;
mCurrentVolume = current;
@@ -600,14 +601,15 @@ public final class MediaController {
}
/**
* Get the stream this is currently controlling volume on. When the volume
* type is {@link MediaSession#PLAYBACK_TYPE_REMOTE} this value does not
* have meaning and should be ignored.
* Get the audio attributes for this session. The attributes will affect
* volume handling for the session. When the volume type is
* {@link MediaSession#PLAYBACK_TYPE_REMOTE} these may be ignored by the
* remote volume handler.
*
* @return The stream this session is playing on.
* @return The attributes for this session.
*/
public int getAudioStream() {
return mAudioStream;
public AudioAttributes getAudioAttributes() {
return mAudioAttrs;
}
/**
@@ -679,7 +681,7 @@ public final class MediaController {
public void onVolumeInfoChanged(ParcelableVolumeInfo pvi) {
MediaController controller = mController.get();
if (controller != null) {
VolumeInfo info = new VolumeInfo(pvi.volumeType, pvi.audioStream, pvi.controlType,
VolumeInfo info = new VolumeInfo(pvi.volumeType, pvi.audioAttrs, pvi.controlType,
pvi.maxVolume, pvi.currentVolume);
controller.postMessage(MSG_UPDATE_VOLUME, info, null);
}

View File

@@ -22,6 +22,7 @@ import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.Rating;
@@ -268,18 +269,22 @@ public final class MediaSession {
}
/**
* Set the stream this session is playing on. This will affect the system's
* volume handling for this session. If {@link #setPlaybackToRemote} was
* previously called it will stop receiving volume commands and the system
* will begin sending volume changes to the appropriate stream.
* Set the attributes for this session's audio. This will affect the
* system's volume handling for this session. If
* {@link #setPlaybackToRemote} was previously called it will stop receiving
* volume commands and the system will begin sending volume changes to the
* appropriate stream.
* <p>
* By default sessions are on {@link AudioManager#STREAM_MUSIC}.
* By default sessions use attributes for media.
*
* @param stream The {@link AudioManager} stream this session is playing on.
* @param attributes The {@link AudioAttributes} for this session's audio.
*/
public void setPlaybackToLocal(int stream) {
public void setPlaybackToLocal(AudioAttributes attributes) {
if (attributes == null) {
throw new IllegalArgumentException("Attributes cannot be null for local playback.");
}
try {
mBinder.configureVolumeHandling(PLAYBACK_TYPE_LOCAL, stream, 0);
mBinder.setPlaybackToLocal(attributes);
} catch (RemoteException e) {
Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
}
@@ -288,9 +293,10 @@ public final class MediaSession {
/**
* Configure this session to use remote volume handling. This must be called
* to receive volume button events, otherwise the system will adjust the
* current stream volume for this session. If {@link #setPlaybackToLocal}
* was previously called that stream will stop receiving volume changes for
* this session.
* appropriate stream volume for this session. If
* {@link #setPlaybackToLocal} was previously called the system will stop
* handling volume changes for this session and pass them to the volume
* provider instead.
*
* @param volumeProvider The provider that will handle volume changes. May
* not be null.
@@ -308,7 +314,7 @@ public final class MediaSession {
});
try {
mBinder.configureVolumeHandling(PLAYBACK_TYPE_REMOTE, volumeProvider.getVolumeControl(),
mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(),
volumeProvider.getMaxVolume());
} catch (RemoteException e) {
Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);

View File

@@ -15,6 +15,7 @@
package android.media.session;
import android.media.AudioAttributes;
import android.os.Parcel;
import android.os.Parcelable;
@@ -26,15 +27,16 @@ import android.os.Parcelable;
*/
public class ParcelableVolumeInfo implements Parcelable {
public int volumeType;
public int audioStream;
public AudioAttributes audioAttrs;
public int controlType;
public int maxVolume;
public int currentVolume;
public ParcelableVolumeInfo(int volumeType, int audioStream, int controlType, int maxVolume,
public ParcelableVolumeInfo(int volumeType, AudioAttributes audioAttrs, int controlType,
int maxVolume,
int currentVolume) {
this.volumeType = volumeType;
this.audioStream = audioStream;
this.audioAttrs = audioAttrs;
this.controlType = controlType;
this.maxVolume = maxVolume;
this.currentVolume = currentVolume;
@@ -42,10 +44,10 @@ public class ParcelableVolumeInfo implements Parcelable {
public ParcelableVolumeInfo(Parcel from) {
volumeType = from.readInt();
audioStream = from.readInt();
controlType = from.readInt();
maxVolume = from.readInt();
currentVolume = from.readInt();
audioAttrs = AudioAttributes.CREATOR.createFromParcel(from);
}
@Override
@@ -56,10 +58,10 @@ public class ParcelableVolumeInfo implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(volumeType);
dest.writeInt(audioStream);
dest.writeInt(controlType);
dest.writeInt(maxVolume);
dest.writeInt(currentVolume);
audioAttrs.writeToParcel(dest, flags);
}

View File

@@ -31,6 +31,7 @@ import android.media.session.MediaSession;
import android.media.session.MediaSessionInfo;
import android.media.session.PlaybackState;
import android.media.session.ParcelableVolumeInfo;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.Rating;
@@ -105,9 +106,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
// End TransportPerformer fields
// Volume handling fields
private AudioAttributes mAudioAttrs;
private AudioManager mAudioManager;
private int mVolumeType = MediaSession.PLAYBACK_TYPE_LOCAL;
private int mAudioStream = AudioManager.STREAM_MUSIC;
private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
private int mMaxVolume = 0;
private int mCurrentVolume = 0;
@@ -131,6 +132,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
mService = service;
mHandler = new MessageHandler(handler.getLooper());
mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
}
/**
@@ -219,7 +221,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
direction = -1;
}
if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
mAudioManager.adjustStreamVolume(mAudioStream, direction, flags);
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
mAudioManager.adjustStreamVolume(stream, direction, flags);
} else {
if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
// Nothing to do, the volume cannot be changed
@@ -245,7 +248,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
public void setVolumeTo(int value, int flags) {
if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
mAudioManager.setStreamVolume(mAudioStream, value, flags);
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
mAudioManager.setStreamVolume(stream, value, flags);
} else {
if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
// Nothing to do. The volume can't be set directly.
@@ -315,8 +319,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
*
* @return The audio stream the session is using.
*/
public int getAudioStream() {
return mAudioStream;
public AudioAttributes getAudioAttributes() {
return mAudioAttrs;
}
/**
@@ -613,36 +617,34 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
}
@Override
public void configureVolumeHandling(int type, int arg1, int arg2) throws RemoteException {
boolean typeChanged = type != mVolumeType;
switch(type) {
case MediaSession.PLAYBACK_TYPE_LOCAL:
mVolumeType = type;
int audioStream = arg1;
if (isValidStream(audioStream)) {
mAudioStream = audioStream;
} else {
Log.e(TAG, "Cannot set stream to " + audioStream + ". Using music stream");
mAudioStream = AudioManager.STREAM_MUSIC;
}
break;
case MediaSession.PLAYBACK_TYPE_REMOTE:
mVolumeType = type;
mVolumeControlType = arg1;
mMaxVolume = arg2;
break;
default:
throw new IllegalArgumentException("Volume handling type " + type
+ " not recognized.");
public void setPlaybackToLocal(AudioAttributes attributes) {
boolean typeChanged;
synchronized (mLock) {
typeChanged = mVolumeType == MediaSession.PLAYBACK_TYPE_REMOTE;
mVolumeType = MediaSession.PLAYBACK_TYPE_LOCAL;
if (attributes != null) {
mAudioAttrs = attributes;
} else {
Log.e(TAG, "Received null audio attributes, using existing attributes");
}
}
if (typeChanged) {
mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
}
}
private boolean isValidStream(int stream) {
return stream >= AudioManager.STREAM_VOICE_CALL
&& stream <= AudioManager.STREAM_NOTIFICATION;
@Override
public void setPlaybackToRemote(int control, int max) {
boolean typeChanged;
synchronized (mLock) {
typeChanged = mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL;
mVolumeType = MediaSession.PLAYBACK_TYPE_REMOTE;
mVolumeControlType = control;
mMaxVolume = max;
}
if (typeChanged) {
mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
}
}
}
@@ -822,11 +824,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
current = mOptimisticVolume != -1 ? mOptimisticVolume
: mCurrentVolume;
} else {
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
type = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
max = mAudioManager.getStreamMaxVolume(mAudioStream);
current = mAudioManager.getStreamVolume(mAudioStream);
max = mAudioManager.getStreamMaxVolume(stream);
current = mAudioManager.getStreamVolume(stream);
}
return new ParcelableVolumeInfo(mVolumeType, mAudioStream, type, max, current);
return new ParcelableVolumeInfo(mVolumeType, mAudioAttrs, type, max, current);
}
}