Merge "Fix remote volume adjustment for Android U"
This commit is contained in:
@@ -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 : "";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user