Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c26fe9bc authored by Iván Budnik's avatar Iván Budnik Committed by Android (Google) Code Review
Browse files

Merge "Fix remote volume adjustment for Android U"

parents d94a307c b8552342
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -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 : "";
    }
+23 −1
Original line number Diff line number Diff line
@@ -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);
    }
}
+8 −23
Original line number Diff line number Diff line
@@ -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,29 +162,19 @@ 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;
    }

    /**
     * Remove a {@code device} from current media.
@@ -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() {
+8 −14
Original line number Diff line number Diff line
@@ -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,24 +1223,17 @@ 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;
        }

        private Token findToken(int stream) {
            synchronized (mRemoteStreams) {
+1 −25
Original line number Diff line number Diff line
@@ -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