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

Commit fe583995 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

MediaRouter2: Fix routes IDs in RoutingSessionInfo

This CL fixes the issue that RoutingSessionInfo#getSelectedRoutes
return improper route IDs when it is recreated.

To ensure provider ID related feature, another test is added.
Since RoutingSessionInfo#setProviderId is a hidden method, the test
is not added to CTS.

The reason for moving "updating route ID logic" into Builder is from
considering use cases.
The original ID of the route is only checked when the provider ID is
set and a route is added to or removed from a RoutingSessionInfo,
which is very rare case.

This CL also fixes the issue that didn't release the previous routing
session when transfer.

Bug: 150666870
Bug: 150751854

Test: atest mediaroutertest
Change-Id: Ic05c11ebf43562b44214eb661c8b9c106f1c9d3e
parent 2b75d73b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ public class MediaRouter2Manager {
                int requestId = mNextRequestId.getAndIncrement();
                mMediaRouterService.requestCreateSessionWithManager(
                        client, sessionInfo.getClientPackageName(), route, requestId);
                //TODO: release the previous session?
                releaseSession(sessionInfo);
            } catch (RemoteException ex) {
                Log.e(TAG, "Unable to select media route", ex);
            }
+29 −36
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
@@ -74,15 +73,10 @@ public final class RoutingSessionInfo implements Parcelable {
        mClientPackageName = builder.mClientPackageName;
        mProviderId = builder.mProviderId;

        // TODO: Needs to check that the routes already have unique IDs.
        mSelectedRoutes = Collections.unmodifiableList(
                convertToUniqueRouteIds(builder.mSelectedRoutes));
        mSelectableRoutes = Collections.unmodifiableList(
                convertToUniqueRouteIds(builder.mSelectableRoutes));
        mDeselectableRoutes = Collections.unmodifiableList(
                convertToUniqueRouteIds(builder.mDeselectableRoutes));
        mTransferableRoutes = Collections.unmodifiableList(
                convertToUniqueRouteIds(builder.mTransferableRoutes));
        mSelectedRoutes = Collections.unmodifiableList(builder.mSelectedRoutes);
        mSelectableRoutes = Collections.unmodifiableList(builder.mSelectableRoutes);
        mDeselectableRoutes = Collections.unmodifiableList(builder.mDeselectableRoutes);
        mTransferableRoutes = Collections.unmodifiableList(builder.mTransferableRoutes);

        mVolumeHandling = builder.mVolumeHandling;
        mVolumeMax = builder.mVolumeMax;
@@ -332,24 +326,6 @@ public final class RoutingSessionInfo implements Parcelable {
        return result.toString();
    }

    private List<String> convertToUniqueRouteIds(@NonNull List<String> routeIds) {
        if (routeIds == null) {
            Log.w(TAG, "routeIds is null. Returning an empty list");
            return Collections.emptyList();
        }

        // mProviderId can be null if not set. Return the original list for this case.
        if (mProviderId == null) {
            return routeIds;
        }

        List<String> result = new ArrayList<>();
        for (String routeId : routeIds) {
            result.add(MediaRouter2Utils.toUniqueId(mProviderId, routeId));
        }
        return result;
    }

    /**
     * Builder class for {@link RoutingSessionInfo}.
     */
@@ -455,6 +431,12 @@ public final class RoutingSessionInfo implements Parcelable {
                throw new IllegalArgumentException("providerId must not be empty");
            }
            mProviderId = providerId;

            mSelectedRoutes.replaceAll(routeId -> getUniqueId(mProviderId, routeId));
            mSelectableRoutes.replaceAll(routeId -> getUniqueId(mProviderId, routeId));
            mDeselectableRoutes.replaceAll(routeId -> getUniqueId(mProviderId, routeId));
            mTransferableRoutes.replaceAll(routeId -> getUniqueId(mProviderId, routeId));

            return this;
        }

@@ -475,7 +457,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mSelectedRoutes.add(routeId);
            mSelectedRoutes.add(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -487,7 +469,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mSelectedRoutes.remove(routeId);
            mSelectedRoutes.remove(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -508,7 +490,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mSelectableRoutes.add(routeId);
            mSelectableRoutes.add(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -520,7 +502,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mSelectableRoutes.remove(routeId);
            mSelectableRoutes.remove(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -541,7 +523,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mDeselectableRoutes.add(routeId);
            mDeselectableRoutes.add(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -553,7 +535,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mDeselectableRoutes.remove(routeId);
            mDeselectableRoutes.remove(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -574,7 +556,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mTransferableRoutes.add(routeId);
            mTransferableRoutes.add(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -586,7 +568,7 @@ public final class RoutingSessionInfo implements Parcelable {
            if (TextUtils.isEmpty(routeId)) {
                throw new IllegalArgumentException("routeId must not be empty");
            }
            mTransferableRoutes.remove(routeId);
            mTransferableRoutes.remove(getUniqueId(mProviderId, routeId));
            return this;
        }

@@ -652,4 +634,15 @@ public final class RoutingSessionInfo implements Parcelable {
            return new RoutingSessionInfo(this);
        }
    }

    private static String getUniqueId(String providerId, String routeId) {
        if (TextUtils.isEmpty(providerId)) {
            return routeId;
        }
        String originalId = MediaRouter2Utils.getOriginalId(routeId);
        if (originalId == null) {
            originalId = routeId;
        }
        return MediaRouter2Utils.toUniqueId(providerId, originalId);
    }
}
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mediaroutertest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import android.media.RoutingSessionInfo;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Tests {@link RoutingSessionInfo} and its {@link RoutingSessionInfo.Builder builder}.
 */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class RoutingSessionInfoTest {
    public static final String TEST_ID = "test_id";
    public static final String TEST_CLIENT_PACKAGE_NAME = "com.test.client.package.name";
    public static final String TEST_NAME = "test_name";

    public static final String TEST_ROUTE_ID_0 = "test_route_type_0";
    public static final String TEST_ROUTE_ID_2 = "test_route_type_2";
    public static final String TEST_ROUTE_ID_4 = "test_route_type_4";
    public static final String TEST_ROUTE_ID_6 = "test_route_type_6";

    public static final String TEST_PROVIDER_ID = "test_provider_id";
    public static final String TEST_OTHER_PROVIDER_ID = "test_other_provider_id";

    // Tests if route IDs are changed properly according to provider ID.
    @Test
    public void testProviderId() {
        RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
                TEST_ID, TEST_CLIENT_PACKAGE_NAME)
                .setName(TEST_NAME)
                .addSelectedRoute(TEST_ROUTE_ID_0)
                .addSelectableRoute(TEST_ROUTE_ID_2)
                .addDeselectableRoute(TEST_ROUTE_ID_4)
                .addTransferableRoute(TEST_ROUTE_ID_6)
                .build();

        RoutingSessionInfo sessionInfoWithProviderId = new RoutingSessionInfo.Builder(sessionInfo)
                .setProviderId(TEST_PROVIDER_ID).build();

        assertNotEquals(sessionInfo.getSelectedRoutes(),
                sessionInfoWithProviderId.getSelectedRoutes());
        assertNotEquals(sessionInfo.getSelectableRoutes(),
                sessionInfoWithProviderId.getSelectableRoutes());
        assertNotEquals(sessionInfo.getDeselectableRoutes(),
                sessionInfoWithProviderId.getDeselectableRoutes());
        assertNotEquals(sessionInfo.getTransferableRoutes(),
                sessionInfoWithProviderId.getTransferableRoutes());

        RoutingSessionInfo sessionInfoWithOtherProviderId =
                new RoutingSessionInfo.Builder(sessionInfoWithProviderId)
                .setProviderId(TEST_OTHER_PROVIDER_ID).build();

        assertNotEquals(sessionInfoWithOtherProviderId.getSelectedRoutes(),
                sessionInfoWithProviderId.getSelectedRoutes());
        assertNotEquals(sessionInfoWithOtherProviderId.getSelectableRoutes(),
                sessionInfoWithProviderId.getSelectableRoutes());
        assertNotEquals(sessionInfoWithOtherProviderId.getDeselectableRoutes(),
                sessionInfoWithProviderId.getDeselectableRoutes());
        assertNotEquals(sessionInfoWithOtherProviderId.getTransferableRoutes(),
                sessionInfoWithProviderId.getTransferableRoutes());

        RoutingSessionInfo sessionInfoWithProviderId2 =
                new RoutingSessionInfo.Builder(sessionInfoWithProviderId).build();

        assertEquals(sessionInfoWithProviderId2.getSelectedRoutes(),
                sessionInfoWithProviderId.getSelectedRoutes());
        assertEquals(sessionInfoWithProviderId2.getSelectableRoutes(),
                sessionInfoWithProviderId.getSelectableRoutes());
        assertEquals(sessionInfoWithProviderId2.getDeselectableRoutes(),
                sessionInfoWithProviderId.getDeselectableRoutes());
        assertEquals(sessionInfoWithProviderId2.getTransferableRoutes(),
                sessionInfoWithProviderId.getTransferableRoutes());
    }
}