Merge "Handles volume for device route and bt routes." into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
73de009a8c
@@ -28,10 +28,12 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.MediaRoute2Info;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
@@ -55,6 +57,9 @@ class BluetoothRouteProvider {
|
||||
@SuppressWarnings("WeakerAccess") /* synthetic access */
|
||||
BluetoothHearingAid mHearingAidProfile;
|
||||
|
||||
// Route type -> volume map
|
||||
private final SparseIntArray mVolumeMap = new SparseIntArray();
|
||||
|
||||
private final Context mContext;
|
||||
private final BluetoothAdapter mBluetoothAdapter;
|
||||
private final BluetoothRoutesUpdatedListener mListener;
|
||||
@@ -192,11 +197,30 @@ class BluetoothRouteProvider {
|
||||
return routes;
|
||||
}
|
||||
|
||||
boolean setSelectedRouteVolume(int volume) {
|
||||
if (mSelectedRoute == null) return false;
|
||||
/**
|
||||
* Updates the volume for {@link AudioManager#getDevicesForStream(int) devices}.
|
||||
*
|
||||
* @return true if devices can be handled by the provider.
|
||||
*/
|
||||
public boolean updateVolumeForDevices(int devices, int volume) {
|
||||
int routeType;
|
||||
if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) {
|
||||
routeType = MediaRoute2Info.TYPE_HEARING_AID;
|
||||
} else if ((devices & (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP
|
||||
| AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
|
||||
| AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
|
||||
routeType = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
mVolumeMap.put(routeType, volume);
|
||||
if (mSelectedRoute == null || mSelectedRoute.route.getType() != routeType) {
|
||||
return true;
|
||||
}
|
||||
mSelectedRoute.route = new MediaRoute2Info.Builder(mSelectedRoute.route)
|
||||
.setVolume(volume)
|
||||
.build();
|
||||
notifyBluetoothRoutesUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -222,6 +246,7 @@ class BluetoothRouteProvider {
|
||||
R.string.bluetooth_a2dp_audio_route_name).toString())
|
||||
.setType(MediaRoute2Info.TYPE_BLUETOOTH_A2DP)
|
||||
.setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
|
||||
.setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
|
||||
.build();
|
||||
newBtRoute.connectedProfiles = new SparseBooleanArray();
|
||||
return newBtRoute;
|
||||
@@ -240,13 +265,10 @@ class BluetoothRouteProvider {
|
||||
// Update volume when the connection state is changed.
|
||||
MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.route)
|
||||
.setConnectionState(state);
|
||||
builder.setType(btRoute.connectedProfiles.get(BluetoothProfile.HEARING_AID, false)
|
||||
? MediaRoute2Info.TYPE_HEARING_AID : MediaRoute2Info.TYPE_BLUETOOTH_A2DP);
|
||||
builder.setType(btRoute.getRouteType());
|
||||
|
||||
if (state == MediaRoute2Info.CONNECTION_STATE_CONNECTED) {
|
||||
int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
|
||||
int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
builder.setVolumeMax(maxVolume).setVolume(currentVolume);
|
||||
builder.setVolume(mVolumeMap.get(btRoute.getRouteType(), 0));
|
||||
}
|
||||
btRoute.route = builder.build();
|
||||
}
|
||||
@@ -259,6 +281,15 @@ class BluetoothRouteProvider {
|
||||
public BluetoothDevice btDevice;
|
||||
public MediaRoute2Info route;
|
||||
public SparseBooleanArray connectedProfiles;
|
||||
|
||||
@MediaRoute2Info.Type
|
||||
int getRouteType() {
|
||||
// Let hearing aid profile have a priority.
|
||||
if (connectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
|
||||
return MediaRoute2Info.TYPE_HEARING_AID;
|
||||
}
|
||||
return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
|
||||
}
|
||||
}
|
||||
|
||||
// These callbacks run on the main thread.
|
||||
@@ -285,13 +316,12 @@ class BluetoothRouteProvider {
|
||||
btRoute = createBluetoothRoute(device);
|
||||
mBluetoothRoutes.put(device.getAddress(), btRoute);
|
||||
}
|
||||
btRoute.connectedProfiles.put(profile, true);
|
||||
if (activeDevices.contains(device)) {
|
||||
mSelectedRoute = btRoute;
|
||||
setRouteConnectionState(mSelectedRoute,
|
||||
MediaRoute2Info.CONNECTION_STATE_CONNECTED);
|
||||
}
|
||||
|
||||
btRoute.connectedProfiles.put(profile, true);
|
||||
}
|
||||
notifyBluetoothRoutesUpdated();
|
||||
}
|
||||
@@ -348,6 +378,8 @@ class BluetoothRouteProvider {
|
||||
BluetoothDevice.ERROR);
|
||||
BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
|
||||
if (bondState == BluetoothDevice.BOND_BONDED && btRoute == null) {
|
||||
//TODO: The type of the new route is A2DP even when it's HEARING_AID.
|
||||
// We may determine the type of route when create the route.
|
||||
btRoute = createBluetoothRoute(device);
|
||||
if (mA2dpProfile != null && mA2dpProfile.getConnectedDevices().contains(device)) {
|
||||
btRoute.connectedProfiles.put(BluetoothProfile.A2DP, true);
|
||||
|
||||
@@ -81,6 +81,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
MediaRoute2Info mDeviceRoute;
|
||||
RoutingSessionInfo mDefaultSessionInfo;
|
||||
final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
|
||||
int mDeviceVolume;
|
||||
|
||||
private final Object mRequestLock = new Object();
|
||||
@GuardedBy("mRequestLock")
|
||||
@@ -127,8 +128,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
});
|
||||
updateSessionInfosIfNeeded();
|
||||
|
||||
mContext.registerReceiver(new VolumeChangeReceiver(),
|
||||
new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
|
||||
IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
|
||||
intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
|
||||
mContext.registerReceiver(new AudioManagerBroadcastReceiver(), intentFilter);
|
||||
|
||||
if (mBtRouteProvider != null) {
|
||||
mHandler.post(() -> {
|
||||
@@ -136,6 +138,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
notifyProviderState();
|
||||
});
|
||||
}
|
||||
updateVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -248,8 +251,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
.setVolumeHandling(mAudioManager.isVolumeFixed()
|
||||
? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
|
||||
: MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
|
||||
.setVolume(mDeviceVolume)
|
||||
.setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
|
||||
.setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
|
||||
.setType(type)
|
||||
.addFeature(FEATURE_LIVE_AUDIO)
|
||||
.addFeature(FEATURE_LIVE_VIDEO)
|
||||
@@ -361,36 +364,43 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
}
|
||||
}
|
||||
|
||||
private class VolumeChangeReceiver extends BroadcastReceiver {
|
||||
void updateVolume() {
|
||||
int devices = mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC);
|
||||
int volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
|
||||
if (mDefaultRoute.getVolume() != volume) {
|
||||
mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute)
|
||||
.setVolume(volume)
|
||||
.build();
|
||||
}
|
||||
|
||||
if (mBtRouteProvider != null && mBtRouteProvider.updateVolumeForDevices(devices, volume)) {
|
||||
return;
|
||||
}
|
||||
if (mDeviceVolume != volume) {
|
||||
mDeviceVolume = volume;
|
||||
mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute)
|
||||
.setVolume(volume)
|
||||
.build();
|
||||
}
|
||||
publishProviderState();
|
||||
}
|
||||
|
||||
private class AudioManagerBroadcastReceiver extends BroadcastReceiver {
|
||||
// This will be called in the main thread.
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
|
||||
if (!intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)
|
||||
&& !intent.getAction().equals(AudioManager.STREAM_DEVICES_CHANGED_ACTION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
|
||||
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
|
||||
if (streamType != AudioManager.STREAM_MUSIC) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
|
||||
final int oldVolume = intent.getIntExtra(
|
||||
AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
|
||||
|
||||
if (newVolume != oldVolume) {
|
||||
if (TextUtils.equals(mDeviceRoute.getId(), mSelectedRouteId)) {
|
||||
mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute)
|
||||
.setVolume(newVolume)
|
||||
.build();
|
||||
} else if (mBtRouteProvider != null) {
|
||||
mBtRouteProvider.setSelectedRouteVolume(newVolume);
|
||||
}
|
||||
mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute)
|
||||
.setVolume(newVolume)
|
||||
.build();
|
||||
publishProviderState();
|
||||
}
|
||||
updateVolume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user