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

Commit 9b10a64b authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

MediaRouter2: Add volume-related info to MediaRoute2Info

Prior to adding volume control functionaly to MediaRouter2,
this CL adds volume-related info to MediaRoute2Info.

From this, MediaRouter2 clients can show the current volume of the remote device.

Volume control logic will be followed by this CL.

Bug: 142298160
Test: atest mediaroutertest
Change-Id: I64a96db9c194e5a5d9aa3ce9b8792c0eb7f2eb4f
parent ab644cb3
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -46,6 +46,21 @@ public final class MediaRoute2Info implements Parcelable {
        }
    };

    /**
     * Playback information indicating the playback volume is fixed, i.e. it cannot be
     * controlled from this object. An example of fixed playback volume is a remote player,
     * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather
     * than attenuate at the source.
     * @see #getVolumeHandling()
     */
    public static final int PLAYBACK_VOLUME_FIXED = 0;
    /**
     * Playback information indicating the playback volume is variable and can be controlled
     * from this object.
     * @see #getVolumeHandling()
     */
    public static final int PLAYBACK_VOLUME_VARIABLE = 1;

    @NonNull
    final String mId;
    @Nullable
@@ -58,6 +73,9 @@ public final class MediaRoute2Info implements Parcelable {
    final String mClientPackageName;
    @NonNull
    final List<String> mSupportedCategories;
    final int mVolume;
    final int mVolumeMax;
    final int mVolumeHandling;
    @Nullable
    final Bundle mExtras;

@@ -68,6 +86,9 @@ public final class MediaRoute2Info implements Parcelable {
        mDescription = builder.mDescription;
        mClientPackageName = builder.mClientPackageName;
        mSupportedCategories = builder.mSupportedCategories;
        mVolume = builder.mVolume;
        mVolumeMax = builder.mVolumeMax;
        mVolumeHandling = builder.mVolumeHandling;
        mExtras = builder.mExtras;
    }

@@ -78,6 +99,9 @@ public final class MediaRoute2Info implements Parcelable {
        mDescription = in.readString();
        mClientPackageName = in.readString();
        mSupportedCategories = in.createStringArrayList();
        mVolume = in.readInt();
        mVolumeMax = in.readInt();
        mVolumeHandling = in.readInt();
        mExtras = in.readBundle();
    }

@@ -111,6 +135,9 @@ public final class MediaRoute2Info implements Parcelable {
                && Objects.equals(mDescription, other.mDescription)
                && Objects.equals(mClientPackageName, other.mClientPackageName)
                && Objects.equals(mSupportedCategories, other.mSupportedCategories)
                && (mVolume == other.mVolume)
                && (mVolumeMax == other.mVolumeMax)
                && (mVolumeHandling == other.mVolumeHandling)
                //TODO: This will be evaluated as false in most cases. Try not to.
                && Objects.equals(mExtras, other.mExtras);
    }
@@ -162,6 +189,29 @@ public final class MediaRoute2Info implements Parcelable {
        return mSupportedCategories;
    }

    /**
     * Gets the current volume of the route. This may be invalid if the route is not selected.
     */
    public int getVolume() {
        return mVolume;
    }

    /**
     * Gets the maximum volume of the route.
     */
    public int getVolumeMax() {
        return mVolumeMax;
    }

    /**
     * Gets information about how volume is handled on the route.
     *
     * @return {@link #PLAYBACK_VOLUME_FIXED} or {@link #PLAYBACK_VOLUME_VARIABLE}
     */
    public int getVolumeHandling() {
        return mVolumeHandling;
    }

    @Nullable
    public Bundle getExtras() {
        return mExtras;
@@ -199,6 +249,9 @@ public final class MediaRoute2Info implements Parcelable {
        dest.writeString(mDescription);
        dest.writeString(mClientPackageName);
        dest.writeStringList(mSupportedCategories);
        dest.writeInt(mVolume);
        dest.writeInt(mVolumeMax);
        dest.writeInt(mVolumeHandling);
        dest.writeBundle(mExtras);
    }

@@ -209,6 +262,9 @@ public final class MediaRoute2Info implements Parcelable {
                .append("id=").append(getId())
                .append(", name=").append(getName())
                .append(", description=").append(getDescription())
                .append(", volume=").append(getVolume())
                .append(", volumeMax=").append(getVolumeMax())
                .append(", volumeHandling=").append(getVolumeHandling())
                .append(", providerId=").append(getProviderId())
                .append(" }");
        return result.toString();
@@ -224,6 +280,9 @@ public final class MediaRoute2Info implements Parcelable {
        String mDescription;
        String mClientPackageName;
        List<String> mSupportedCategories;
        int mVolume;
        int mVolumeMax;
        int mVolumeHandling;
        Bundle mExtras;

        public Builder(@NonNull String id, @NonNull String name) {
@@ -251,6 +310,9 @@ public final class MediaRoute2Info implements Parcelable {
            mDescription = routeInfo.mDescription;
            setClientPackageName(routeInfo.mClientPackageName);
            setSupportedCategories(routeInfo.mSupportedCategories);
            setVolume(routeInfo.mVolume);
            setVolumeMax(routeInfo.mVolumeMax);
            setVolumeHandling(routeInfo.mVolumeHandling);
            if (routeInfo.mExtras != null) {
                mExtras = new Bundle(routeInfo.mExtras);
            }
@@ -344,6 +406,32 @@ public final class MediaRoute2Info implements Parcelable {
            return this;
        }

        /**
         * Sets the route's current volume, or 0 if unknown.
         */
        @NonNull
        public Builder setVolume(int volume) {
            mVolume = volume;
            return this;
        }

        /**
         * Sets the route's maximum volume, or 0 if unknown.
         */
        @NonNull
        public Builder setVolumeMax(int volumeMax) {
            mVolumeMax = volumeMax;
            return this;
        }

        /**
         * Sets the route's volume handling.
         */
        @NonNull
        public Builder setVolumeHandling(int volumeHandling) {
            mVolumeHandling = volumeHandling;
            return this;
        }
        /**
         * Sets a bundle of extras for the route.
         */
+20 −0
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
    public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
    public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";

    public static final int VOLUME_MAX = 100;
    public static final String ROUTE_ID_FIXED_VOLUME = "route_fixed_volume";
    public static final String ROUTE_NAME_FIXED_VOLUME = "Fixed Volume Route";
    public static final String ROUTE_ID_VARIABLE_VOLUME = "route_variable_volume";
    public static final String ROUTE_NAME_VARIABLE_VOLUME = "Variable Volume Route";

    public static final String ACTION_REMOVE_ROUTE =
            "com.android.mediarouteprovider.action_remove_route";

@@ -58,9 +64,23 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
                        .addSupportedCategory(CATEGORY_SAMPLE)
                        .addSupportedCategory(CATEGORY_SPECIAL)
                        .build();
        MediaRoute2Info fixedVolumeRoute =
                new MediaRoute2Info.Builder(ROUTE_ID_FIXED_VOLUME, ROUTE_NAME_FIXED_VOLUME)
                        .addSupportedCategory(CATEGORY_SAMPLE)
                        .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_FIXED)
                        .build();
        MediaRoute2Info variableVolumeRoute =
                new MediaRoute2Info.Builder(ROUTE_ID_VARIABLE_VOLUME, ROUTE_NAME_VARIABLE_VOLUME)
                        .addSupportedCategory(CATEGORY_SAMPLE)
                        .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
                        .setVolumeMax(VOLUME_MAX)
                        .build();

        mRoutes.put(route1.getId(), route1);
        mRoutes.put(route2.getId(), route2);
        mRoutes.put(routeSpecial.getId(), routeSpecial);
        mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute);
        mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute);
    }

    @Override
+30 −1
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.mediaroutertest;

import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
@@ -61,6 +64,12 @@ public class MediaRouterManagerTest {
    public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
    public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";

    public static final int VOLUME_MAX = 100;
    public static final String ROUTE_ID_FIXED_VOLUME = "route_fixed_volume";
    public static final String ROUTE_NAME_FIXED_VOLUME = "Fixed Volume Route";
    public static final String ROUTE_ID_VARIABLE_VOLUME = "route_variable_volume";
    public static final String ROUTE_NAME_VARIABLE_VOLUME = "Variable Volume Route";

    public static final String ACTION_REMOVE_ROUTE =
            "com.android.mediarouteprovider.action_remove_route";

@@ -98,7 +107,7 @@ public class MediaRouterManagerTest {
        mPackageName = mContext.getPackageName();
    }

    //TODO: Move to a seperate file
    //TODO: Move to a separate file
    @Test
    public void testMediaRoute2Info() {
        MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder("id", "name")
@@ -281,6 +290,26 @@ public class MediaRouterManagerTest {
        mManager.unregisterCallback(managerCallback);
    }

    @Test
    public void testVolumeHandling() {
        MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class);

        mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
        mRouter2.registerCallback(mExecutor, mockCallback);
        verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
                .onRoutesChanged(argThat(routes -> routes.size() > 0));
        Map<String, MediaRoute2Info> routes = createRouteMap(mRouter2.getRoutes());

        MediaRoute2Info fixedVolumeRoute = routes.get(ROUTE_ID_FIXED_VOLUME);
        MediaRoute2Info variableVolumeRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);

        assertEquals(PLAYBACK_VOLUME_FIXED, fixedVolumeRoute.getVolumeHandling());
        assertEquals(PLAYBACK_VOLUME_VARIABLE, variableVolumeRoute.getVolumeHandling());
        assertEquals(VOLUME_MAX, variableVolumeRoute.getVolumeMax());

        mRouter2.unregisterCallback(mockCallback);
    }

    // Helper for getting routes easily
    static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
        Map<String, MediaRoute2Info> routeMap = new HashMap<>();