Merge "Fix remote volume adjustment for Android U"

This commit is contained in:
Iván Budnik
2022-06-07 13:30:31 +00:00
committed by Android (Google) Code Review
5 changed files with 80 additions and 65 deletions

View File

@@ -18,6 +18,7 @@ package android.media;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -48,6 +49,9 @@ public final class RoutingSessionInfo implements Parcelable {
private static final String TAG = "RoutingSessionInfo";
private static final String KEY_GROUP_ROUTE = "androidx.mediarouter.media.KEY_GROUP_ROUTE";
private static final String KEY_VOLUME_HANDLING = "volumeHandling";
final String mId;
final CharSequence mName;
final String mOwnerPackageName;
@@ -67,6 +71,7 @@ public final class RoutingSessionInfo implements Parcelable {
final Bundle mControlHints;
final boolean mIsSystemSession;
RoutingSessionInfo(@NonNull Builder builder) {
Objects.requireNonNull(builder, "builder must not be null.");
@@ -85,12 +90,17 @@ public final class RoutingSessionInfo implements Parcelable {
mTransferableRoutes = Collections.unmodifiableList(
convertToUniqueRouteIds(builder.mTransferableRoutes));
mVolumeHandling = builder.mVolumeHandling;
mVolumeMax = builder.mVolumeMax;
mVolume = builder.mVolume;
mControlHints = builder.mControlHints;
mIsSystemSession = builder.mIsSystemSession;
boolean volumeAdjustmentForRemoteGroupSessions = Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
mVolumeHandling = defineVolumeHandling(builder.mVolumeHandling, mSelectedRoutes,
volumeAdjustmentForRemoteGroupSessions);
mControlHints = updateVolumeHandlingInHints(builder.mControlHints, mVolumeHandling);
}
RoutingSessionInfo(@NonNull Parcel src) {
@@ -115,6 +125,34 @@ public final class RoutingSessionInfo implements Parcelable {
mIsSystemSession = src.readBoolean();
}
private static Bundle updateVolumeHandlingInHints(Bundle controlHints, int volumeHandling) {
// Workaround to preserve retro-compatibility with androidx.
// See b/228021646 for more details.
if (controlHints != null && controlHints.containsKey(KEY_GROUP_ROUTE)) {
Bundle groupRoute = controlHints.getBundle(KEY_GROUP_ROUTE);
if (groupRoute != null && groupRoute.containsKey(KEY_VOLUME_HANDLING)
&& volumeHandling != groupRoute.getInt(KEY_VOLUME_HANDLING)) {
//Creating copy of controlHints with updated value.
Bundle newGroupRoute = new Bundle(groupRoute);
newGroupRoute.putInt(KEY_VOLUME_HANDLING, volumeHandling);
Bundle newControlHints = new Bundle(controlHints);
newControlHints.putBundle(KEY_GROUP_ROUTE, newGroupRoute);
return newControlHints;
}
}
//Return same Bundle.
return controlHints;
}
private static int defineVolumeHandling(int volumeHandling, List<String> selectedRoutes,
boolean volumeAdjustmentForRemoteGroupSessions) {
if (!volumeAdjustmentForRemoteGroupSessions && selectedRoutes.size() > 1) {
return MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
}
return volumeHandling;
}
private static String ensureString(String str) {
return str != null ? str : "";
}

View File

@@ -19,10 +19,12 @@ package com.android.mediaroutertest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import android.content.res.Resources;
import android.media.MediaRoute2Info;
import android.media.RoutingSessionInfo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -94,4 +96,24 @@ public class RoutingSessionInfoTest {
assertEquals(sessionInfoWithProviderId2.getTransferableRoutes(),
sessionInfoWithProviderId.getTransferableRoutes());
}
@Test
public void testGetVolumeHandlingGroupSession() {
RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
TEST_ID, TEST_CLIENT_PACKAGE_NAME)
.setName(TEST_NAME)
.addSelectedRoute(TEST_ROUTE_ID_0)
.addSelectedRoute(TEST_ROUTE_ID_2)
.setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
.build();
boolean volumeAdjustmentForRemoteGroupSessions = Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
int expectedResult = volumeAdjustmentForRemoteGroupSessions
? MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE :
MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
assertEquals(sessionInfo.getVolumeHandling(), expectedResult);
}
}

View File

@@ -73,7 +73,6 @@ public class InfoMediaManager extends MediaManager {
MediaRouter2Manager mRouterManager;
@VisibleForTesting
String mPackageName;
private final boolean mVolumeAdjustmentForRemoteGroupSessions;
private MediaDevice mCurrentConnectedDevice;
private LocalBluetoothManager mBluetoothManager;
@@ -87,9 +86,6 @@ public class InfoMediaManager extends MediaManager {
if (!TextUtils.isEmpty(packageName)) {
mPackageName = packageName;
}
mVolumeAdjustmentForRemoteGroupSessions = context.getResources().getBoolean(
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
}
@Override
@@ -166,28 +162,18 @@ public class InfoMediaManager extends MediaManager {
}
boolean isRoutingSessionAvailableForVolumeControl() {
if (mVolumeAdjustmentForRemoteGroupSessions) {
return true;
}
List<RoutingSessionInfo> sessions =
mRouterManager.getRoutingSessions(mPackageName);
boolean foundNonSystemSession = false;
boolean isGroup = false;
for (RoutingSessionInfo session : sessions) {
if (!session.isSystemSession()) {
foundNonSystemSession = true;
int selectedRouteCount = session.getSelectedRoutes().size();
if (selectedRouteCount > 1) {
isGroup = true;
break;
}
if (!session.isSystemSession()
&& session.getVolumeHandling() != MediaRoute2Info.PLAYBACK_VOLUME_FIXED) {
return true;
}
}
if (!foundNonSystemSession) {
Log.d(TAG, "No routing session for " + mPackageName);
return false;
}
return !isGroup;
Log.d(TAG, "No routing session for " + mPackageName);
return false;
}
/**
@@ -418,8 +404,7 @@ public class InfoMediaManager extends MediaManager {
@TargetApi(Build.VERSION_CODES.R)
boolean shouldEnableVolumeSeekBar(RoutingSessionInfo sessionInfo) {
return sessionInfo.isSystemSession() // System sessions are not remote
|| mVolumeAdjustmentForRemoteGroupSessions
|| sessionInfo.getSelectedRoutes().size() <= 1;
|| sessionInfo.getVolumeHandling() != MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
}
private void refreshDevices() {

View File

@@ -35,6 +35,7 @@ import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.IVolumeController;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;
import android.media.VolumePolicy;
@@ -1222,23 +1223,16 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
String packageName = ctr.getPackageName();
List<RoutingSessionInfo> sessions =
mRouter2Manager.getRoutingSessions(packageName);
boolean foundNonSystemSession = false;
boolean isGroup = false;
for (RoutingSessionInfo session : sessions) {
if (!session.isSystemSession()) {
foundNonSystemSession = true;
int selectedRouteCount = session.getSelectedRoutes().size();
if (selectedRouteCount > 1) {
isGroup = true;
break;
}
if (!session.isSystemSession()
&& session.getVolumeHandling() != MediaRoute2Info.PLAYBACK_VOLUME_FIXED) {
return true;
}
}
if (!foundNonSystemSession) {
Log.d(TAG, "No routing session for " + packageName);
return false;
}
return !isGroup;
Log.d(TAG, "No routing session for " + packageName);
return false;
}
private Token findToken(int stream) {

View File

@@ -26,9 +26,7 @@ import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.MediaMetadata;
import android.media.MediaRouter2Manager;
import android.media.Rating;
import android.media.RoutingSessionInfo;
import android.media.VolumeProvider;
import android.media.session.ISession;
import android.media.session.ISessionCallback;
@@ -463,29 +461,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
@Override
public boolean canHandleVolumeKey() {
if (isPlaybackTypeLocal() || mVolumeAdjustmentForRemoteGroupSessions) {
return true;
}
MediaRouter2Manager mRouter2Manager = MediaRouter2Manager.getInstance(mContext);
List<RoutingSessionInfo> sessions =
mRouter2Manager.getRoutingSessions(mPackageName);
boolean foundNonSystemSession = false;
boolean isGroup = false;
for (RoutingSessionInfo session : sessions) {
if (!session.isSystemSession()) {
foundNonSystemSession = true;
int selectedRouteCount = session.getSelectedRoutes().size();
if (selectedRouteCount > 1) {
isGroup = true;
break;
}
}
}
if (!foundNonSystemSession) {
Log.d(TAG, "No routing session for " + mPackageName);
return false;
}
return !isGroup;
return mVolumeControlType != VolumeProvider.VOLUME_CONTROL_FIXED;
}
@Override