diff options
| author | 2020-01-11 16:12:59 +0000 | |
|---|---|---|
| committer | 2020-01-11 16:12:59 +0000 | |
| commit | 9b90671746595f04a631c0bbeea4f74fe5a4031f (patch) | |
| tree | 5389dabf415ba81a368df6b24a9511652e1e32e6 | |
| parent | 94bd736a3a00a2452cff6f7ab38740bb1a0da01c (diff) | |
| parent | 459dee33dfadaa0881d4ce6fddf788e5193a6014 (diff) | |
Merge "RouteSessionInfo: Remove isValid() and override equals()/hashCode()"
5 files changed, 651 insertions, 105 deletions
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java index e4b85b279d1b..8333b0f96c17 100644 --- a/media/java/android/media/MediaRoute2ProviderService.java +++ b/media/java/android/media/MediaRoute2ProviderService.java @@ -145,7 +145,6 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Updates the information of a session. * If the session is destroyed or not created before, it will be ignored. - * A session will be destroyed if it has no selected route. * Call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify clients of * session info changes. * @@ -156,10 +155,6 @@ public abstract class MediaRoute2ProviderService extends Service { public final void updateSessionInfo(@NonNull RouteSessionInfo sessionInfo) { Objects.requireNonNull(sessionInfo, "sessionInfo must not be null"); String sessionId = sessionInfo.getId(); - if (sessionInfo.getSelectedRoutes().isEmpty()) { - releaseSession(sessionId); - return; - } synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { diff --git a/media/java/android/media/RouteSessionInfo.java b/media/java/android/media/RouteSessionInfo.java index 41f06c327e46..def5197874a5 100644 --- a/media/java/android/media/RouteSessionInfo.java +++ b/media/java/android/media/RouteSessionInfo.java @@ -33,8 +33,7 @@ import java.util.Objects; * Describes a route session that is made when a media route is selected. * @hide */ -public class RouteSessionInfo implements Parcelable { - +public final class RouteSessionInfo implements Parcelable { @NonNull public static final Creator<RouteSessionInfo> CREATOR = new Creator<RouteSessionInfo>() { @@ -70,6 +69,7 @@ public class RouteSessionInfo implements Parcelable { mRouteFeature = builder.mRouteFeature; mProviderId = builder.mProviderId; + // TODO: Needs to check that the routes already have unique IDs. mSelectedRoutes = Collections.unmodifiableList( convertToUniqueRouteIds(builder.mSelectedRoutes)); mSelectableRoutes = Collections.unmodifiableList( @@ -113,18 +113,6 @@ public class RouteSessionInfo implements Parcelable { } /** - * Returns whether the session info is valid or not - * - * TODO in this CL: Remove this method. - */ - public boolean isValid() { - return !TextUtils.isEmpty(mId) - && !TextUtils.isEmpty(mClientPackageName) - && !TextUtils.isEmpty(mRouteFeature) - && mSelectedRoutes.size() > 0; - } - - /** * Gets the id of the session. The sessions which are given by {@link MediaRouter2} will have * unique IDs. * <p> @@ -236,6 +224,32 @@ public class RouteSessionInfo implements Parcelable { } @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof RouteSessionInfo)) { + return false; + } + + RouteSessionInfo other = (RouteSessionInfo) obj; + return Objects.equals(mId, other.mId) + && Objects.equals(mClientPackageName, other.mClientPackageName) + && Objects.equals(mRouteFeature, other.mRouteFeature) + && Objects.equals(mProviderId, other.mProviderId) + && Objects.equals(mSelectedRoutes, other.mSelectedRoutes) + && Objects.equals(mSelectableRoutes, other.mSelectableRoutes) + && Objects.equals(mDeselectableRoutes, other.mDeselectableRoutes) + && Objects.equals(mTransferrableRoutes, other.mTransferrableRoutes); + } + + @Override + public int hashCode() { + return Objects.hash(mId, mClientPackageName, mRouteFeature, mProviderId, + mSelectedRoutes, mSelectableRoutes, mDeselectableRoutes, mTransferrableRoutes); + } + + @Override public String toString() { StringBuilder result = new StringBuilder() .append("RouteSessionInfo{ ") @@ -297,6 +311,10 @@ public class RouteSessionInfo implements Parcelable { * {@link MediaRoute2ProviderService}. * </p> * + * @param id ID of the session. Must not be empty. + * @param clientPackageName package name of the client app which uses this session. + * If is is unknown, then just use an empty string. + * @param routeFeature the route feature of session. Must not be empty. * @see MediaRoute2Info#getId() */ public Builder(@NonNull String id, @NonNull String clientPackageName, @@ -304,10 +322,14 @@ public class RouteSessionInfo implements Parcelable { if (TextUtils.isEmpty(id)) { throw new IllegalArgumentException("id must not be empty"); } + Objects.requireNonNull(clientPackageName, "clientPackageName must not be null"); + if (TextUtils.isEmpty(routeFeature)) { + throw new IllegalArgumentException("routeFeature must not be empty"); + } + mId = id; - mClientPackageName = Objects.requireNonNull( - clientPackageName, "clientPackageName must not be null"); - mRouteFeature = Objects.requireNonNull(routeFeature, "routeFeature must not be null"); + mClientPackageName = clientPackageName; + mRouteFeature = routeFeature; mSelectedRoutes = new ArrayList<>(); mSelectableRoutes = new ArrayList<>(); mDeselectableRoutes = new ArrayList<>(); @@ -338,8 +360,6 @@ public class RouteSessionInfo implements Parcelable { /** * Sets the provider ID of the session. - * Also, calling this method will make all type of route IDs be unique by adding - * {@code providerId:} as a prefix. So do NOT call this method twice on same instance. * * @hide */ @@ -362,20 +382,26 @@ public class RouteSessionInfo implements Parcelable { } /** - * Adds a route to the selected routes. + * Adds a route to the selected routes. The {@code routeId} must not be empty. */ @NonNull public Builder addSelectedRoute(@NonNull String routeId) { - mSelectedRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mSelectedRoutes.add(routeId); return this; } /** - * Removes a route from the selected routes. + * Removes a route from the selected routes. The {@code routeId} must not be empty. */ @NonNull public Builder removeSelectedRoute(@NonNull String routeId) { - mSelectedRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mSelectedRoutes.remove(routeId); return this; } @@ -389,20 +415,26 @@ public class RouteSessionInfo implements Parcelable { } /** - * Adds a route to the selectable routes. + * Adds a route to the selectable routes. The {@code routeId} must not be empty. */ @NonNull public Builder addSelectableRoute(@NonNull String routeId) { - mSelectableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mSelectableRoutes.add(routeId); return this; } /** - * Removes a route from the selectable routes. + * Removes a route from the selectable routes. The {@code routeId} must not be empty. */ @NonNull public Builder removeSelectableRoute(@NonNull String routeId) { - mSelectableRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mSelectableRoutes.remove(routeId); return this; } @@ -416,20 +448,26 @@ public class RouteSessionInfo implements Parcelable { } /** - * Adds a route to the deselectable routes. + * Adds a route to the deselectable routes. The {@code routeId} must not be empty. */ @NonNull public Builder addDeselectableRoute(@NonNull String routeId) { - mDeselectableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mDeselectableRoutes.add(routeId); return this; } /** - * Removes a route from the deselectable routes. + * Removes a route from the deselectable routes. The {@code routeId} must not be empty. */ @NonNull public Builder removeDeselectableRoute(@NonNull String routeId) { - mDeselectableRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mDeselectableRoutes.remove(routeId); return this; } @@ -443,21 +481,26 @@ public class RouteSessionInfo implements Parcelable { } /** - * Adds a route to the transferrable routes. + * Adds a route to the transferrable routes. The {@code routeId} must not be empty. */ @NonNull public Builder addTransferrableRoute(@NonNull String routeId) { - mTransferrableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mTransferrableRoutes.add(routeId); return this; } /** - * Removes a route from the transferrable routes. + * Removes a route from the transferrable routes. The {@code routeId} must not be empty. */ @NonNull public Builder removeTransferrableRoute(@NonNull String routeId) { - mTransferrableRoutes.remove( - Objects.requireNonNull(routeId, "routeId must not be null")); + if (TextUtils.isEmpty(routeId)) { + throw new IllegalArgumentException("routeId must not be empty"); + } + mTransferrableRoutes.remove(routeId); return this; } @@ -472,9 +515,14 @@ public class RouteSessionInfo implements Parcelable { /** * Builds a route session info. + * + * @throws IllegalArgumentException if no selected routes are added. */ @NonNull public RouteSessionInfo build() { + if (mSelectedRoutes.isEmpty()) { + throw new IllegalArgumentException("selectedRoutes must not be empty"); + } return new RouteSessionInfo(this); } } diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java index 27bcfc8c532a..b81c378ad2ba 100644 --- a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java +++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java @@ -237,13 +237,20 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService MediaRoute2Info route = mRoutes.get(routeId); mRouteSessionMap.remove(routeId); - if (sessionInfo == null || route == null) { + if (sessionInfo == null || route == null + || !sessionInfo.getSelectedRoutes().contains(routeId)) { return; } + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) .setClientPackageName(null) .build()); + if (sessionInfo.getSelectedRoutes().size() == 1) { + releaseSession(sessionId); + return; + } + RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .removeSelectedRoute(routeId) .addSelectableRoute(routeId) diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteSessionInfoTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteSessionInfoTest.java new file mode 100644 index 000000000000..6d21b3326521 --- /dev/null +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteSessionInfoTest.java @@ -0,0 +1,559 @@ +/* + * Copyright 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 static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.testng.Assert.assertThrows; + +import android.media.RouteSessionInfo; +import android.os.Bundle; +import android.os.Parcel; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests {@link RouteSessionInfo} and its {@link RouteSessionInfo.Builder builder}. + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class RouteSessionInfoTest { + 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_ROUTE_FEATURE = "test_route_feature"; + + public static final String TEST_ROUTE_ID_0 = "test_route_type_0"; + public static final String TEST_ROUTE_ID_1 = "test_route_type_1"; + public static final String TEST_ROUTE_ID_2 = "test_route_type_2"; + public static final String TEST_ROUTE_ID_3 = "test_route_type_3"; + public static final String TEST_ROUTE_ID_4 = "test_route_type_4"; + public static final String TEST_ROUTE_ID_5 = "test_route_type_5"; + public static final String TEST_ROUTE_ID_6 = "test_route_type_6"; + public static final String TEST_ROUTE_ID_7 = "test_route_type_7"; + + public static final String TEST_KEY = "test_key"; + public static final String TEST_VALUE = "test_value"; + + @Test + public void testBuilderConstructorWithInvalidValues() { + final String nullId = null; + final String nullClientPackageName = null; + final String nullRouteFeature = null; + + final String emptyId = ""; + // Note: An empty string as client package name is valid. + final String emptyRouteFeature = ""; + + final String validId = TEST_ID; + final String validClientPackageName = TEST_CLIENT_PACKAGE_NAME; + final String validRouteFeature = TEST_ROUTE_FEATURE; + + // ID is invalid + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + nullId, validClientPackageName, validRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + emptyId, validClientPackageName, validRouteFeature)); + + // client package name is invalid (null) + assertThrows(NullPointerException.class, () -> new RouteSessionInfo.Builder( + validId, nullClientPackageName, validRouteFeature)); + + // route feature is invalid + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + validId, validClientPackageName, nullRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + validId, validClientPackageName, emptyRouteFeature)); + + // Two arguments are invalid - (1) ID and clientPackageName + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + nullId, nullClientPackageName, validRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + emptyId, nullClientPackageName, validRouteFeature)); + + // Two arguments are invalid - (2) ID and routeFeature + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + nullId, validClientPackageName, nullRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + nullId, validClientPackageName, emptyRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + emptyId, validClientPackageName, nullRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + emptyId, validClientPackageName, emptyRouteFeature)); + + // Two arguments are invalid - (3) clientPackageName and routeFeature + // Note that this throws NullPointerException. + assertThrows(NullPointerException.class, () -> new RouteSessionInfo.Builder( + validId, nullClientPackageName, nullRouteFeature)); + assertThrows(NullPointerException.class, () -> new RouteSessionInfo.Builder( + validId, nullClientPackageName, emptyRouteFeature)); + + // All arguments are invalid + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + nullId, nullClientPackageName, nullRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + nullId, nullClientPackageName, emptyRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + emptyId, nullClientPackageName, nullRouteFeature)); + assertThrows(IllegalArgumentException.class, () -> new RouteSessionInfo.Builder( + emptyId, nullClientPackageName, emptyRouteFeature)); + + // Null RouteInfo (1-argument constructor) + final RouteSessionInfo nullRouteSessionInfo = null; + assertThrows(NullPointerException.class, + () -> new RouteSessionInfo.Builder(nullRouteSessionInfo)); + } + + @Test + public void testBuilderConstructorWithEmptyClientPackageName() { + // An empty string for client package name is valid. (for unknown cases) + // Creating builder with it should not throw any exception. + RouteSessionInfo.Builder builder = new RouteSessionInfo.Builder( + TEST_ID, "" /* clientPackageName*/, TEST_ROUTE_FEATURE); + } + + @Test + public void testBuilderBuildWithEmptySelectedRoutesThrowsIAE() { + RouteSessionInfo.Builder builder = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE); + // Note: Calling build() without adding any selected routes. + assertThrows(IllegalArgumentException.class, () -> builder.build()); + } + + @Test + public void testBuilderAddRouteMethodsWithIllegalArgumentsThrowsIAE() { + RouteSessionInfo.Builder builder = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE); + + final String nullRouteId = null; + final String emptyRouteId = ""; + + assertThrows(IllegalArgumentException.class, + () -> builder.addSelectedRoute(nullRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.addSelectableRoute(nullRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.addDeselectableRoute(nullRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.addTransferrableRoute(nullRouteId)); + + assertThrows(IllegalArgumentException.class, + () -> builder.addSelectedRoute(emptyRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.addSelectableRoute(emptyRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.addDeselectableRoute(emptyRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.addTransferrableRoute(emptyRouteId)); + } + + @Test + public void testBuilderRemoveRouteMethodsWithIllegalArgumentsThrowsIAE() { + RouteSessionInfo.Builder builder = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE); + + final String nullRouteId = null; + final String emptyRouteId = ""; + + assertThrows(IllegalArgumentException.class, + () -> builder.removeSelectedRoute(nullRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.removeSelectableRoute(nullRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.removeDeselectableRoute(nullRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.removeTransferrableRoute(nullRouteId)); + + assertThrows(IllegalArgumentException.class, + () -> builder.removeSelectedRoute(emptyRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.removeSelectableRoute(emptyRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.removeDeselectableRoute(emptyRouteId)); + assertThrows(IllegalArgumentException.class, + () -> builder.removeTransferrableRoute(emptyRouteId)); + } + + @Test + public void testBuilderAndGettersOfRouteSessionInfo() { + Bundle controlHints = new Bundle(); + controlHints.putString(TEST_KEY, TEST_VALUE); + + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .setControlHints(controlHints) + .build(); + + assertEquals(TEST_ID, sessionInfo.getId()); + assertEquals(TEST_CLIENT_PACKAGE_NAME, sessionInfo.getClientPackageName()); + assertEquals(TEST_ROUTE_FEATURE, sessionInfo.getRouteFeature()); + + assertEquals(2, sessionInfo.getSelectedRoutes().size()); + assertEquals(TEST_ROUTE_ID_0, sessionInfo.getSelectedRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_1, sessionInfo.getSelectedRoutes().get(1)); + + assertEquals(2, sessionInfo.getSelectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_2, sessionInfo.getSelectableRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_3, sessionInfo.getSelectableRoutes().get(1)); + + assertEquals(2, sessionInfo.getDeselectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_4, sessionInfo.getDeselectableRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_5, sessionInfo.getDeselectableRoutes().get(1)); + + assertEquals(2, sessionInfo.getTransferrableRoutes().size()); + assertEquals(TEST_ROUTE_ID_6, sessionInfo.getTransferrableRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_7, sessionInfo.getTransferrableRoutes().get(1)); + + Bundle controlHintsOut = sessionInfo.getControlHints(); + assertNotNull(controlHintsOut); + assertTrue(controlHintsOut.containsKey(TEST_KEY)); + assertEquals(TEST_VALUE, controlHintsOut.getString(TEST_KEY)); + } + + @Test + public void testBuilderAddRouteMethodsWithBuilderCopyConstructor() { + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .build(); + + RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .build(); + + assertEquals(2, newSessionInfo.getSelectedRoutes().size()); + assertEquals(TEST_ROUTE_ID_0, newSessionInfo.getSelectedRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_1, newSessionInfo.getSelectedRoutes().get(1)); + + assertEquals(2, newSessionInfo.getSelectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_2, newSessionInfo.getSelectableRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_3, newSessionInfo.getSelectableRoutes().get(1)); + + assertEquals(2, newSessionInfo.getDeselectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_4, newSessionInfo.getDeselectableRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_5, newSessionInfo.getDeselectableRoutes().get(1)); + + assertEquals(2, newSessionInfo.getTransferrableRoutes().size()); + assertEquals(TEST_ROUTE_ID_6, newSessionInfo.getTransferrableRoutes().get(0)); + assertEquals(TEST_ROUTE_ID_7, newSessionInfo.getTransferrableRoutes().get(1)); + } + + @Test + public void testBuilderRemoveRouteMethods() { + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .removeSelectedRoute(TEST_ROUTE_ID_1) + + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .removeSelectableRoute(TEST_ROUTE_ID_3) + + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .removeDeselectableRoute(TEST_ROUTE_ID_5) + + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .removeTransferrableRoute(TEST_ROUTE_ID_7) + + .build(); + + assertEquals(1, sessionInfo.getSelectedRoutes().size()); + assertEquals(TEST_ROUTE_ID_0, sessionInfo.getSelectedRoutes().get(0)); + + assertEquals(1, sessionInfo.getSelectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_2, sessionInfo.getSelectableRoutes().get(0)); + + assertEquals(1, sessionInfo.getDeselectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_4, sessionInfo.getDeselectableRoutes().get(0)); + + assertEquals(1, sessionInfo.getTransferrableRoutes().size()); + assertEquals(TEST_ROUTE_ID_6, sessionInfo.getTransferrableRoutes().get(0)); + } + + @Test + public void testBuilderRemoveRouteMethodsWithBuilderCopyConstructor() { + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .build(); + + RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) + .removeSelectedRoute(TEST_ROUTE_ID_1) + .removeSelectableRoute(TEST_ROUTE_ID_3) + .removeDeselectableRoute(TEST_ROUTE_ID_5) + .removeTransferrableRoute(TEST_ROUTE_ID_7) + .build(); + + assertEquals(1, newSessionInfo.getSelectedRoutes().size()); + assertEquals(TEST_ROUTE_ID_0, newSessionInfo.getSelectedRoutes().get(0)); + + assertEquals(1, newSessionInfo.getSelectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_2, newSessionInfo.getSelectableRoutes().get(0)); + + assertEquals(1, newSessionInfo.getDeselectableRoutes().size()); + assertEquals(TEST_ROUTE_ID_4, newSessionInfo.getDeselectableRoutes().get(0)); + + assertEquals(1, newSessionInfo.getTransferrableRoutes().size()); + assertEquals(TEST_ROUTE_ID_6, newSessionInfo.getTransferrableRoutes().get(0)); + } + + @Test + public void testBuilderClearRouteMethods() { + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .clearSelectedRoutes() + + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .clearSelectableRoutes() + + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .clearDeselectableRoutes() + + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .clearTransferrableRoutes() + + // SelectedRoutes must not be empty + .addSelectedRoute(TEST_ROUTE_ID_0) + .build(); + + assertEquals(1, sessionInfo.getSelectedRoutes().size()); + assertEquals(TEST_ROUTE_ID_0, sessionInfo.getSelectedRoutes().get(0)); + + assertTrue(sessionInfo.getSelectableRoutes().isEmpty()); + assertTrue(sessionInfo.getDeselectableRoutes().isEmpty()); + assertTrue(sessionInfo.getTransferrableRoutes().isEmpty()); + } + + @Test + public void testBuilderClearRouteMethodsWithBuilderCopyConstructor() { + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .build(); + + RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) + .clearSelectedRoutes() + .clearSelectableRoutes() + .clearDeselectableRoutes() + .clearTransferrableRoutes() + // SelectedRoutes must not be empty + .addSelectedRoute(TEST_ROUTE_ID_0) + .build(); + + assertEquals(1, newSessionInfo.getSelectedRoutes().size()); + assertEquals(TEST_ROUTE_ID_0, newSessionInfo.getSelectedRoutes().get(0)); + + assertTrue(newSessionInfo.getSelectableRoutes().isEmpty()); + assertTrue(newSessionInfo.getDeselectableRoutes().isEmpty()); + assertTrue(newSessionInfo.getTransferrableRoutes().isEmpty()); + } + + @Test + public void testEqualsCreatedWithSameArguments() { + Bundle controlHints = new Bundle(); + controlHints.putString(TEST_KEY, TEST_VALUE); + + RouteSessionInfo sessionInfo1 = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .setControlHints(controlHints) + .build(); + + RouteSessionInfo sessionInfo2 = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .setControlHints(controlHints) + .build(); + + assertEquals(sessionInfo1, sessionInfo2); + assertEquals(sessionInfo1.hashCode(), sessionInfo2.hashCode()); + } + + @Test + public void testEqualsCreatedWithBuilderCopyConstructor() { + Bundle controlHints = new Bundle(); + controlHints.putString(TEST_KEY, TEST_VALUE); + + RouteSessionInfo sessionInfo1 = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .setControlHints(controlHints) + .build(); + + RouteSessionInfo sessionInfo2 = new RouteSessionInfo.Builder(sessionInfo1).build(); + + assertEquals(sessionInfo1, sessionInfo2); + assertEquals(sessionInfo1.hashCode(), sessionInfo2.hashCode()); + } + + @Test + public void testEqualsReturnFalse() { + Bundle controlHints = new Bundle(); + controlHints.putString(TEST_KEY, TEST_VALUE); + + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .setControlHints(controlHints) + .build(); + + // Now, we will use copy constructor + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .addSelectedRoute("randomRoute") + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .addSelectableRoute("randomRoute") + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .addDeselectableRoute("randomRoute") + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .addTransferrableRoute("randomRoute") + .build()); + + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .removeSelectedRoute(TEST_ROUTE_ID_1) + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .removeSelectableRoute(TEST_ROUTE_ID_3) + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .removeDeselectableRoute(TEST_ROUTE_ID_5) + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .removeTransferrableRoute(TEST_ROUTE_ID_7) + .build()); + + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .clearSelectedRoutes() + // Note: Calling build() with empty selected routes will throw IAE. + .addSelectedRoute(TEST_ROUTE_ID_0) + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .clearSelectableRoutes() + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .clearDeselectableRoutes() + .build()); + assertNotEquals(sessionInfo, new RouteSessionInfo.Builder(sessionInfo) + .clearTransferrableRoutes() + .build()); + + // Note: ControlHints will not affect the equals. + } + + @Test + public void testParcelingAndUnParceling() { + Bundle controlHints = new Bundle(); + controlHints.putString(TEST_KEY, TEST_VALUE); + + RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( + TEST_ID, TEST_CLIENT_PACKAGE_NAME, TEST_ROUTE_FEATURE) + .addSelectedRoute(TEST_ROUTE_ID_0) + .addSelectedRoute(TEST_ROUTE_ID_1) + .addSelectableRoute(TEST_ROUTE_ID_2) + .addSelectableRoute(TEST_ROUTE_ID_3) + .addDeselectableRoute(TEST_ROUTE_ID_4) + .addDeselectableRoute(TEST_ROUTE_ID_5) + .addTransferrableRoute(TEST_ROUTE_ID_6) + .addTransferrableRoute(TEST_ROUTE_ID_7) + .setControlHints(controlHints) + .build(); + + Parcel parcel = Parcel.obtain(); + sessionInfo.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + RouteSessionInfo sessionInfoFromParcel = RouteSessionInfo.CREATOR.createFromParcel(parcel); + assertEquals(sessionInfo, sessionInfoFromParcel); + assertEquals(sessionInfo.hashCode(), sessionInfoFromParcel.hashCode()); + + // Check controlHints + Bundle controlHintsOut = sessionInfoFromParcel.getControlHints(); + assertNotNull(controlHintsOut); + assertTrue(controlHintsOut.containsKey(TEST_KEY)); + assertEquals(TEST_VALUE, controlHintsOut.getString(TEST_KEY)); + } +} diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteSessionTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteSessionTest.java deleted file mode 100644 index 9971fc3bbe9f..000000000000 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteSessionTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2019 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.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.media.RouteSessionInfo; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class RouteSessionTest { - private static final String TEST_SESSION_ID = "test_session_id"; - private static final String TEST_PACKAGE_NAME = "com.android.mediaroutertest"; - private static final String TEST_CONTROL_CATEGORY = "com.android.mediaroutertest.category"; - - private static final String TEST_ROUTE_ID1 = "route_id1"; - - @Test - public void testValidity() { - RouteSessionInfo emptyPackageSession = new RouteSessionInfo.Builder(TEST_SESSION_ID, - "", - TEST_CONTROL_CATEGORY) - .addSelectedRoute(TEST_ROUTE_ID1) - .build(); - RouteSessionInfo emptyCategorySession = new RouteSessionInfo.Builder(TEST_SESSION_ID, - TEST_PACKAGE_NAME, "") - .addSelectedRoute(TEST_ROUTE_ID1) - .build(); - - RouteSessionInfo emptySelectedRouteSession = new RouteSessionInfo.Builder(TEST_SESSION_ID, - TEST_PACKAGE_NAME, TEST_CONTROL_CATEGORY) - .build(); - - RouteSessionInfo validSession = new RouteSessionInfo.Builder(emptySelectedRouteSession) - .addSelectedRoute(TEST_ROUTE_ID1) - .build(); - - assertFalse(emptyPackageSession.isValid()); - assertFalse(emptyCategorySession.isValid()); - assertFalse(emptySelectedRouteSession.isValid()); - assertTrue(validSession.isValid()); - } -} |