Loading media/java/android/media/MediaRoute2Info.java +180 −1 Original line number Diff line number Diff line Loading @@ -16,13 +16,17 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.List; Loading @@ -46,6 +50,34 @@ public final class MediaRoute2Info implements Parcelable { } }; /** @hide */ @IntDef({CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING, CONNECTION_STATE_CONNECTED}) @Retention(RetentionPolicy.SOURCE) private @interface ConnectionState {} /** * The default connection state indicating the route is disconnected. * * @see #getConnectionState */ public static final int CONNECTION_STATE_DISCONNECTED = 0; /** * A connection state indicating the route is in the process of connecting and is not yet * ready for use. * * @see #getConnectionState */ public static final int CONNECTION_STATE_CONNECTING = 1; /** * A connection state indicating the route is connected. * * @see #getConnectionState */ public static final int CONNECTION_STATE_CONNECTED = 2; /** * 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, Loading @@ -61,6 +93,46 @@ public final class MediaRoute2Info implements Parcelable { */ public static final int PLAYBACK_VOLUME_VARIABLE = 1; /** @hide */ @IntDef({ DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_TV, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_BLUETOOTH}) @Retention(RetentionPolicy.SOURCE) private @interface DeviceType {} /** * The default receiver device type of the route indicating the type is unknown. * * @see #getDeviceType * @hide */ public static final int DEVICE_TYPE_UNKNOWN = 0; /** * A receiver device type of the route indicating the presentation of the media is happening * on a TV. * * @see #getDeviceType */ public static final int DEVICE_TYPE_TV = 1; /** * A receiver device type of the route indicating the presentation of the media is happening * on a speaker. * * @see #getDeviceType */ public static final int DEVICE_TYPE_SPEAKER = 2; /** * A receiver device type of the route indicating the presentation of the media is happening * on a bluetooth device such as a bluetooth speaker. * * @see #getDeviceType * @hide */ public static final int DEVICE_TYPE_BLUETOOTH = 3; @NonNull final String mId; @Nullable Loading @@ -70,12 +142,17 @@ public final class MediaRoute2Info implements Parcelable { @Nullable final CharSequence mDescription; @Nullable final @ConnectionState int mConnectionState; @Nullable final Uri mIconUri; @Nullable final String mClientPackageName; @NonNull final List<String> mSupportedCategories; final int mVolume; final int mVolumeMax; final int mVolumeHandling; final @DeviceType int mDeviceType; @Nullable final Bundle mExtras; Loading @@ -86,11 +163,14 @@ public final class MediaRoute2Info implements Parcelable { mProviderId = builder.mProviderId; mName = builder.mName; mDescription = builder.mDescription; mConnectionState = builder.mConnectionState; mIconUri = builder.mIconUri; mClientPackageName = builder.mClientPackageName; mSupportedCategories = builder.mSupportedCategories; mVolume = builder.mVolume; mVolumeMax = builder.mVolumeMax; mVolumeHandling = builder.mVolumeHandling; mDeviceType = builder.mDeviceType; mExtras = builder.mExtras; mUniqueId = createUniqueId(); } Loading @@ -100,11 +180,14 @@ public final class MediaRoute2Info implements Parcelable { mProviderId = in.readString(); mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mConnectionState = in.readInt(); mIconUri = in.readParcelable(null); mClientPackageName = in.readString(); mSupportedCategories = in.createStringArrayList(); mVolume = in.readInt(); mVolumeMax = in.readInt(); mVolumeHandling = in.readInt(); mDeviceType = in.readInt(); mExtras = in.readBundle(); mUniqueId = createUniqueId(); } Loading Loading @@ -145,18 +228,22 @@ public final class MediaRoute2Info implements Parcelable { && Objects.equals(mProviderId, other.mProviderId) && Objects.equals(mName, other.mName) && Objects.equals(mDescription, other.mDescription) && (mConnectionState == other.mConnectionState) && Objects.equals(mIconUri, other.mIconUri) && Objects.equals(mClientPackageName, other.mClientPackageName) && Objects.equals(mSupportedCategories, other.mSupportedCategories) && (mVolume == other.mVolume) && (mVolumeMax == other.mVolumeMax) && (mVolumeHandling == other.mVolumeHandling) && (mDeviceType == other.mDeviceType) //TODO: This will be evaluated as false in most cases. Try not to. && Objects.equals(mExtras, other.mExtras); } @Override public int hashCode() { return Objects.hash(mId, mName, mDescription, mSupportedCategories); return Objects.hash(mId, mName, mDescription, mConnectionState, mIconUri, mSupportedCategories, mVolume, mVolumeMax, mVolumeHandling, mDeviceType); } /** Loading Loading @@ -203,6 +290,29 @@ public final class MediaRoute2Info implements Parcelable { return mDescription; } /** * Gets the connection state of the route. * * @return The connection state of this route: {@link #CONNECTION_STATE_DISCONNECTED}, * {@link #CONNECTION_STATE_CONNECTING}, or {@link #CONNECTION_STATE_CONNECTED}. */ @ConnectionState public int getConnectionState() { return mConnectionState; } /** * Gets the URI of the icon representing this route. * <p> * This icon will be used in picker UIs if available. * * @return The URI of the icon representing this route, or null if none. */ @Nullable public Uri getIconUri() { return mIconUri; } /** * Gets the package name of the client that uses the route. * Returns null if no clients use this. Loading @@ -221,6 +331,18 @@ public final class MediaRoute2Info implements Parcelable { return mSupportedCategories; } //TODO: once device types are confirmed, reflect those into the comment. /** * Gets the type of the receiver device associated with this route. * * @return The type of the receiver device associated with this route: * {@link #DEVICE_TYPE_TV} or {@link #DEVICE_TYPE_SPEAKER}. */ @DeviceType public int getDeviceType() { return mDeviceType; } /** * Gets the current volume of the route. This may be invalid if the route is not selected. */ Loading Loading @@ -293,11 +415,14 @@ public final class MediaRoute2Info implements Parcelable { dest.writeString(mProviderId); TextUtils.writeToParcel(mName, dest, flags); TextUtils.writeToParcel(mDescription, dest, flags); dest.writeInt(mConnectionState); dest.writeParcelable(mIconUri, flags); dest.writeString(mClientPackageName); dest.writeStringList(mSupportedCategories); dest.writeInt(mVolume); dest.writeInt(mVolumeMax); dest.writeInt(mVolumeHandling); dest.writeInt(mDeviceType); dest.writeBundle(mExtras); } Loading @@ -308,9 +433,12 @@ public final class MediaRoute2Info implements Parcelable { .append("id=").append(getId()) .append(", name=").append(getName()) .append(", description=").append(getDescription()) .append(", connectionState=").append(getConnectionState()) .append(", iconUri=").append(getIconUri()) .append(", volume=").append(getVolume()) .append(", volumeMax=").append(getVolumeMax()) .append(", volumeHandling=").append(getVolumeHandling()) .append(", deviceType=").append(getDeviceType()) .append(", providerId=").append(getProviderId()) .append(" }"); return result.toString(); Loading @@ -324,11 +452,16 @@ public final class MediaRoute2Info implements Parcelable { String mProviderId; CharSequence mName; CharSequence mDescription; @ConnectionState int mConnectionState; Uri mIconUri; String mClientPackageName; List<String> mSupportedCategories; int mVolume; int mVolumeMax; int mVolumeHandling = PLAYBACK_VOLUME_FIXED; @DeviceType int mDeviceType = DEVICE_TYPE_UNKNOWN; Bundle mExtras; public Builder(@NonNull String id, @NonNull CharSequence name) { Loading @@ -348,11 +481,14 @@ public final class MediaRoute2Info implements Parcelable { } setName(routeInfo.mName); mDescription = routeInfo.mDescription; mConnectionState = routeInfo.mConnectionState; mIconUri = routeInfo.mIconUri; setClientPackageName(routeInfo.mClientPackageName); setSupportedCategories(routeInfo.mSupportedCategories); setVolume(routeInfo.mVolume); setVolumeMax(routeInfo.mVolumeMax); setVolumeHandling(routeInfo.mVolumeHandling); setDeviceType(routeInfo.mDeviceType); if (routeInfo.mExtras != null) { mExtras = new Bundle(routeInfo.mExtras); } Loading Loading @@ -402,6 +538,39 @@ public final class MediaRoute2Info implements Parcelable { return this; } /** * Sets the route's connection state. * * {@link #CONNECTION_STATE_DISCONNECTED}, * {@link #CONNECTION_STATE_CONNECTING}, or * {@link #CONNECTION_STATE_CONNECTED}. */ @NonNull public Builder setConnectionState(@ConnectionState int connectionState) { mConnectionState = connectionState; return this; } /** * Sets the URI of the icon representing this route. * <p> * This icon will be used in picker UIs if available. * </p><p> * The URI must be one of the following formats: * <ul> * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) * </li> * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> * </ul> * </p> */ @NonNull public Builder setIconUri(@Nullable Uri iconUri) { mIconUri = iconUri; return this; } /** * Sets the package name of the app using the route. */ Loading Loading @@ -470,6 +639,16 @@ public final class MediaRoute2Info implements Parcelable { mVolumeHandling = volumeHandling; return this; } /** * Sets the route's device type. */ @NonNull public Builder setDeviceType(@DeviceType int deviceType) { mDeviceType = deviceType; return this; } /** * Sets a bundle of extras for the route. */ Loading media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java +7 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.mediarouteprovider.example; import static android.media.MediaRoute2Info.DEVICE_TYPE_SPEAKER; import static android.media.MediaRoute2Info.DEVICE_TYPE_TV; import android.content.Intent; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; Loading Loading @@ -57,9 +60,11 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService private void initializeRoutes() { MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1) .addSupportedCategory(CATEGORY_SAMPLE) .setDeviceType(DEVICE_TYPE_TV) .build(); MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2) .addSupportedCategory(CATEGORY_SAMPLE) .setDeviceType(DEVICE_TYPE_SPEAKER) .build(); MediaRoute2Info routeSpecial = new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_CATEGORY, ROUTE_NAME_SPECIAL_CATEGORY) Loading Loading @@ -123,7 +128,8 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService @Override public void onControlRequest(String routeId, Intent request) { if (ACTION_REMOVE_ROUTE.equals(request.getAction())) { String action = request.getAction(); if (ACTION_REMOVE_ROUTE.equals(action)) { MediaRoute2Info route = mRoutes.get(routeId); if (route != null) { mRoutes.remove(routeId); Loading media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java +96 −0 Original line number Diff line number Diff line Loading @@ -16,19 +16,31 @@ package com.android.mediaroutertest; import static android.media.MediaRoute2Info.CONNECTION_STATE_CONNECTED; import static android.media.MediaRoute2Info.CONNECTION_STATE_CONNECTING; import static android.media.MediaRoute2Info.DEVICE_TYPE_SPEAKER; import static android.media.MediaRoute2Info.DEVICE_TYPE_TV; import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED; import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORIES_ALL; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORIES_SPECIAL; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORY_SAMPLE; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORY_SPECIAL; import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID_SPECIAL_CATEGORY; import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID_VARIABLE_VOLUME; import static com.android.mediaroutertest.MediaRouterManagerTest.SYSTEM_PROVIDER_ID; 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 android.content.Context; import android.media.MediaRoute2Info; import android.media.MediaRouter2; import android.net.Uri; import android.os.Parcel; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; Loading Loading @@ -87,6 +99,90 @@ public class MediaRouter2Test { assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY)); } @Test public void testRouteInfoEquality() { MediaRoute2Info routeInfo = new MediaRoute2Info.Builder("id", "name") .setDescription("description") .setClientPackageName("com.android.mediaroutertest") .setConnectionState(CONNECTION_STATE_CONNECTING) .setIconUri(new Uri.Builder().path("icon").build()) .setVolume(5) .setVolumeMax(20) .addSupportedCategory(CATEGORY_SAMPLE) .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) .setDeviceType(DEVICE_TYPE_SPEAKER) .build(); MediaRoute2Info routeInfoRebuilt = new MediaRoute2Info.Builder(routeInfo).build(); assertEquals(routeInfo, routeInfoRebuilt); Parcel parcel = Parcel.obtain(); parcel.writeParcelable(routeInfo, 0); parcel.setDataPosition(0); MediaRoute2Info routeInfoFromParcel = parcel.readParcelable(null); assertEquals(routeInfo, routeInfoFromParcel); } @Test public void testRouteInfoInequality() { MediaRoute2Info route = new MediaRoute2Info.Builder("id", "name") .setDescription("description") .setClientPackageName("com.android.mediaroutertest") .setConnectionState(CONNECTION_STATE_CONNECTING) .setIconUri(new Uri.Builder().path("icon").build()) .addSupportedCategory(CATEGORY_SAMPLE) .setVolume(5) .setVolumeMax(20) .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) .setDeviceType(DEVICE_TYPE_SPEAKER) .build(); MediaRoute2Info routeId = new MediaRoute2Info.Builder(route) .setId("another id").build(); assertNotEquals(route, routeId); MediaRoute2Info routeName = new MediaRoute2Info.Builder(route) .setName("another name").build(); assertNotEquals(route, routeName); MediaRoute2Info routeDescription = new MediaRoute2Info.Builder(route) .setDescription("another description").build(); assertNotEquals(route, routeDescription); MediaRoute2Info routeConnectionState = new MediaRoute2Info.Builder(route) .setConnectionState(CONNECTION_STATE_CONNECTED).build(); assertNotEquals(route, routeConnectionState); MediaRoute2Info routeIcon = new MediaRoute2Info.Builder(route) .setIconUri(new Uri.Builder().path("new icon").build()).build(); assertNotEquals(route, routeIcon); MediaRoute2Info routeClient = new MediaRoute2Info.Builder(route) .setClientPackageName("another.client.package").build(); assertNotEquals(route, routeClient); MediaRoute2Info routeCategory = new MediaRoute2Info.Builder(route) .addSupportedCategory(CATEGORY_SPECIAL).build(); assertNotEquals(route, routeCategory); MediaRoute2Info routeVolume = new MediaRoute2Info.Builder(route) .setVolume(10).build(); assertNotEquals(route, routeVolume); MediaRoute2Info routeVolumeMax = new MediaRoute2Info.Builder(route) .setVolumeMax(30).build(); assertNotEquals(route, routeVolumeMax); MediaRoute2Info routeVolumeHandling = new MediaRoute2Info.Builder(route) .setVolumeHandling(PLAYBACK_VOLUME_FIXED).build(); assertNotEquals(route, routeVolumeHandling); MediaRoute2Info routeDeviceType = new MediaRoute2Info.Builder(route) .setVolume(DEVICE_TYPE_TV).build(); assertNotEquals(route, routeDeviceType); } @Test public void testControlVolumeWithRouter() throws Exception { Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_ALL); Loading media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java +1 −18 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ 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; import static org.junit.Assert.assertTrue; Loading Loading @@ -124,20 +123,6 @@ public class MediaRouterManagerTest { clearCallbacks(); } //TODO: Move to a separate file @Test public void testMediaRoute2Info() { MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder("id", "name") .build(); MediaRoute2Info routeInfo2 = new MediaRoute2Info.Builder(routeInfo1).build(); MediaRoute2Info routeInfo3 = new MediaRoute2Info.Builder(routeInfo1) .setClientPackageName(mPackageName).build(); assertEquals(routeInfo1, routeInfo2); assertNotEquals(routeInfo1, routeInfo3); } /** * Tests if routes are added correctly when a new callback is registered. */ Loading Loading @@ -177,8 +162,6 @@ public class MediaRouterManagerTest { } }); //TODO: Figure out a more proper way to test. // (Control requests shouldn't be used in this way.) mRouter2.sendControlRequest(routes.get(ROUTE_ID2), new Intent(ACTION_REMOVE_ROUTE)); assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } Loading Loading
media/java/android/media/MediaRoute2Info.java +180 −1 Original line number Diff line number Diff line Loading @@ -16,13 +16,17 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.List; Loading @@ -46,6 +50,34 @@ public final class MediaRoute2Info implements Parcelable { } }; /** @hide */ @IntDef({CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING, CONNECTION_STATE_CONNECTED}) @Retention(RetentionPolicy.SOURCE) private @interface ConnectionState {} /** * The default connection state indicating the route is disconnected. * * @see #getConnectionState */ public static final int CONNECTION_STATE_DISCONNECTED = 0; /** * A connection state indicating the route is in the process of connecting and is not yet * ready for use. * * @see #getConnectionState */ public static final int CONNECTION_STATE_CONNECTING = 1; /** * A connection state indicating the route is connected. * * @see #getConnectionState */ public static final int CONNECTION_STATE_CONNECTED = 2; /** * 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, Loading @@ -61,6 +93,46 @@ public final class MediaRoute2Info implements Parcelable { */ public static final int PLAYBACK_VOLUME_VARIABLE = 1; /** @hide */ @IntDef({ DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_TV, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_BLUETOOTH}) @Retention(RetentionPolicy.SOURCE) private @interface DeviceType {} /** * The default receiver device type of the route indicating the type is unknown. * * @see #getDeviceType * @hide */ public static final int DEVICE_TYPE_UNKNOWN = 0; /** * A receiver device type of the route indicating the presentation of the media is happening * on a TV. * * @see #getDeviceType */ public static final int DEVICE_TYPE_TV = 1; /** * A receiver device type of the route indicating the presentation of the media is happening * on a speaker. * * @see #getDeviceType */ public static final int DEVICE_TYPE_SPEAKER = 2; /** * A receiver device type of the route indicating the presentation of the media is happening * on a bluetooth device such as a bluetooth speaker. * * @see #getDeviceType * @hide */ public static final int DEVICE_TYPE_BLUETOOTH = 3; @NonNull final String mId; @Nullable Loading @@ -70,12 +142,17 @@ public final class MediaRoute2Info implements Parcelable { @Nullable final CharSequence mDescription; @Nullable final @ConnectionState int mConnectionState; @Nullable final Uri mIconUri; @Nullable final String mClientPackageName; @NonNull final List<String> mSupportedCategories; final int mVolume; final int mVolumeMax; final int mVolumeHandling; final @DeviceType int mDeviceType; @Nullable final Bundle mExtras; Loading @@ -86,11 +163,14 @@ public final class MediaRoute2Info implements Parcelable { mProviderId = builder.mProviderId; mName = builder.mName; mDescription = builder.mDescription; mConnectionState = builder.mConnectionState; mIconUri = builder.mIconUri; mClientPackageName = builder.mClientPackageName; mSupportedCategories = builder.mSupportedCategories; mVolume = builder.mVolume; mVolumeMax = builder.mVolumeMax; mVolumeHandling = builder.mVolumeHandling; mDeviceType = builder.mDeviceType; mExtras = builder.mExtras; mUniqueId = createUniqueId(); } Loading @@ -100,11 +180,14 @@ public final class MediaRoute2Info implements Parcelable { mProviderId = in.readString(); mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mConnectionState = in.readInt(); mIconUri = in.readParcelable(null); mClientPackageName = in.readString(); mSupportedCategories = in.createStringArrayList(); mVolume = in.readInt(); mVolumeMax = in.readInt(); mVolumeHandling = in.readInt(); mDeviceType = in.readInt(); mExtras = in.readBundle(); mUniqueId = createUniqueId(); } Loading Loading @@ -145,18 +228,22 @@ public final class MediaRoute2Info implements Parcelable { && Objects.equals(mProviderId, other.mProviderId) && Objects.equals(mName, other.mName) && Objects.equals(mDescription, other.mDescription) && (mConnectionState == other.mConnectionState) && Objects.equals(mIconUri, other.mIconUri) && Objects.equals(mClientPackageName, other.mClientPackageName) && Objects.equals(mSupportedCategories, other.mSupportedCategories) && (mVolume == other.mVolume) && (mVolumeMax == other.mVolumeMax) && (mVolumeHandling == other.mVolumeHandling) && (mDeviceType == other.mDeviceType) //TODO: This will be evaluated as false in most cases. Try not to. && Objects.equals(mExtras, other.mExtras); } @Override public int hashCode() { return Objects.hash(mId, mName, mDescription, mSupportedCategories); return Objects.hash(mId, mName, mDescription, mConnectionState, mIconUri, mSupportedCategories, mVolume, mVolumeMax, mVolumeHandling, mDeviceType); } /** Loading Loading @@ -203,6 +290,29 @@ public final class MediaRoute2Info implements Parcelable { return mDescription; } /** * Gets the connection state of the route. * * @return The connection state of this route: {@link #CONNECTION_STATE_DISCONNECTED}, * {@link #CONNECTION_STATE_CONNECTING}, or {@link #CONNECTION_STATE_CONNECTED}. */ @ConnectionState public int getConnectionState() { return mConnectionState; } /** * Gets the URI of the icon representing this route. * <p> * This icon will be used in picker UIs if available. * * @return The URI of the icon representing this route, or null if none. */ @Nullable public Uri getIconUri() { return mIconUri; } /** * Gets the package name of the client that uses the route. * Returns null if no clients use this. Loading @@ -221,6 +331,18 @@ public final class MediaRoute2Info implements Parcelable { return mSupportedCategories; } //TODO: once device types are confirmed, reflect those into the comment. /** * Gets the type of the receiver device associated with this route. * * @return The type of the receiver device associated with this route: * {@link #DEVICE_TYPE_TV} or {@link #DEVICE_TYPE_SPEAKER}. */ @DeviceType public int getDeviceType() { return mDeviceType; } /** * Gets the current volume of the route. This may be invalid if the route is not selected. */ Loading Loading @@ -293,11 +415,14 @@ public final class MediaRoute2Info implements Parcelable { dest.writeString(mProviderId); TextUtils.writeToParcel(mName, dest, flags); TextUtils.writeToParcel(mDescription, dest, flags); dest.writeInt(mConnectionState); dest.writeParcelable(mIconUri, flags); dest.writeString(mClientPackageName); dest.writeStringList(mSupportedCategories); dest.writeInt(mVolume); dest.writeInt(mVolumeMax); dest.writeInt(mVolumeHandling); dest.writeInt(mDeviceType); dest.writeBundle(mExtras); } Loading @@ -308,9 +433,12 @@ public final class MediaRoute2Info implements Parcelable { .append("id=").append(getId()) .append(", name=").append(getName()) .append(", description=").append(getDescription()) .append(", connectionState=").append(getConnectionState()) .append(", iconUri=").append(getIconUri()) .append(", volume=").append(getVolume()) .append(", volumeMax=").append(getVolumeMax()) .append(", volumeHandling=").append(getVolumeHandling()) .append(", deviceType=").append(getDeviceType()) .append(", providerId=").append(getProviderId()) .append(" }"); return result.toString(); Loading @@ -324,11 +452,16 @@ public final class MediaRoute2Info implements Parcelable { String mProviderId; CharSequence mName; CharSequence mDescription; @ConnectionState int mConnectionState; Uri mIconUri; String mClientPackageName; List<String> mSupportedCategories; int mVolume; int mVolumeMax; int mVolumeHandling = PLAYBACK_VOLUME_FIXED; @DeviceType int mDeviceType = DEVICE_TYPE_UNKNOWN; Bundle mExtras; public Builder(@NonNull String id, @NonNull CharSequence name) { Loading @@ -348,11 +481,14 @@ public final class MediaRoute2Info implements Parcelable { } setName(routeInfo.mName); mDescription = routeInfo.mDescription; mConnectionState = routeInfo.mConnectionState; mIconUri = routeInfo.mIconUri; setClientPackageName(routeInfo.mClientPackageName); setSupportedCategories(routeInfo.mSupportedCategories); setVolume(routeInfo.mVolume); setVolumeMax(routeInfo.mVolumeMax); setVolumeHandling(routeInfo.mVolumeHandling); setDeviceType(routeInfo.mDeviceType); if (routeInfo.mExtras != null) { mExtras = new Bundle(routeInfo.mExtras); } Loading Loading @@ -402,6 +538,39 @@ public final class MediaRoute2Info implements Parcelable { return this; } /** * Sets the route's connection state. * * {@link #CONNECTION_STATE_DISCONNECTED}, * {@link #CONNECTION_STATE_CONNECTING}, or * {@link #CONNECTION_STATE_CONNECTED}. */ @NonNull public Builder setConnectionState(@ConnectionState int connectionState) { mConnectionState = connectionState; return this; } /** * Sets the URI of the icon representing this route. * <p> * This icon will be used in picker UIs if available. * </p><p> * The URI must be one of the following formats: * <ul> * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) * </li> * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> * </ul> * </p> */ @NonNull public Builder setIconUri(@Nullable Uri iconUri) { mIconUri = iconUri; return this; } /** * Sets the package name of the app using the route. */ Loading Loading @@ -470,6 +639,16 @@ public final class MediaRoute2Info implements Parcelable { mVolumeHandling = volumeHandling; return this; } /** * Sets the route's device type. */ @NonNull public Builder setDeviceType(@DeviceType int deviceType) { mDeviceType = deviceType; return this; } /** * Sets a bundle of extras for the route. */ Loading
media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java +7 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.mediarouteprovider.example; import static android.media.MediaRoute2Info.DEVICE_TYPE_SPEAKER; import static android.media.MediaRoute2Info.DEVICE_TYPE_TV; import android.content.Intent; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; Loading Loading @@ -57,9 +60,11 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService private void initializeRoutes() { MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1) .addSupportedCategory(CATEGORY_SAMPLE) .setDeviceType(DEVICE_TYPE_TV) .build(); MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2) .addSupportedCategory(CATEGORY_SAMPLE) .setDeviceType(DEVICE_TYPE_SPEAKER) .build(); MediaRoute2Info routeSpecial = new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_CATEGORY, ROUTE_NAME_SPECIAL_CATEGORY) Loading Loading @@ -123,7 +128,8 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService @Override public void onControlRequest(String routeId, Intent request) { if (ACTION_REMOVE_ROUTE.equals(request.getAction())) { String action = request.getAction(); if (ACTION_REMOVE_ROUTE.equals(action)) { MediaRoute2Info route = mRoutes.get(routeId); if (route != null) { mRoutes.remove(routeId); Loading
media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java +96 −0 Original line number Diff line number Diff line Loading @@ -16,19 +16,31 @@ package com.android.mediaroutertest; import static android.media.MediaRoute2Info.CONNECTION_STATE_CONNECTED; import static android.media.MediaRoute2Info.CONNECTION_STATE_CONNECTING; import static android.media.MediaRoute2Info.DEVICE_TYPE_SPEAKER; import static android.media.MediaRoute2Info.DEVICE_TYPE_TV; import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED; import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORIES_ALL; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORIES_SPECIAL; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORY_SAMPLE; import static com.android.mediaroutertest.MediaRouterManagerTest.CATEGORY_SPECIAL; import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID_SPECIAL_CATEGORY; import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID_VARIABLE_VOLUME; import static com.android.mediaroutertest.MediaRouterManagerTest.SYSTEM_PROVIDER_ID; 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 android.content.Context; import android.media.MediaRoute2Info; import android.media.MediaRouter2; import android.net.Uri; import android.os.Parcel; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; Loading Loading @@ -87,6 +99,90 @@ public class MediaRouter2Test { assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY)); } @Test public void testRouteInfoEquality() { MediaRoute2Info routeInfo = new MediaRoute2Info.Builder("id", "name") .setDescription("description") .setClientPackageName("com.android.mediaroutertest") .setConnectionState(CONNECTION_STATE_CONNECTING) .setIconUri(new Uri.Builder().path("icon").build()) .setVolume(5) .setVolumeMax(20) .addSupportedCategory(CATEGORY_SAMPLE) .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) .setDeviceType(DEVICE_TYPE_SPEAKER) .build(); MediaRoute2Info routeInfoRebuilt = new MediaRoute2Info.Builder(routeInfo).build(); assertEquals(routeInfo, routeInfoRebuilt); Parcel parcel = Parcel.obtain(); parcel.writeParcelable(routeInfo, 0); parcel.setDataPosition(0); MediaRoute2Info routeInfoFromParcel = parcel.readParcelable(null); assertEquals(routeInfo, routeInfoFromParcel); } @Test public void testRouteInfoInequality() { MediaRoute2Info route = new MediaRoute2Info.Builder("id", "name") .setDescription("description") .setClientPackageName("com.android.mediaroutertest") .setConnectionState(CONNECTION_STATE_CONNECTING) .setIconUri(new Uri.Builder().path("icon").build()) .addSupportedCategory(CATEGORY_SAMPLE) .setVolume(5) .setVolumeMax(20) .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) .setDeviceType(DEVICE_TYPE_SPEAKER) .build(); MediaRoute2Info routeId = new MediaRoute2Info.Builder(route) .setId("another id").build(); assertNotEquals(route, routeId); MediaRoute2Info routeName = new MediaRoute2Info.Builder(route) .setName("another name").build(); assertNotEquals(route, routeName); MediaRoute2Info routeDescription = new MediaRoute2Info.Builder(route) .setDescription("another description").build(); assertNotEquals(route, routeDescription); MediaRoute2Info routeConnectionState = new MediaRoute2Info.Builder(route) .setConnectionState(CONNECTION_STATE_CONNECTED).build(); assertNotEquals(route, routeConnectionState); MediaRoute2Info routeIcon = new MediaRoute2Info.Builder(route) .setIconUri(new Uri.Builder().path("new icon").build()).build(); assertNotEquals(route, routeIcon); MediaRoute2Info routeClient = new MediaRoute2Info.Builder(route) .setClientPackageName("another.client.package").build(); assertNotEquals(route, routeClient); MediaRoute2Info routeCategory = new MediaRoute2Info.Builder(route) .addSupportedCategory(CATEGORY_SPECIAL).build(); assertNotEquals(route, routeCategory); MediaRoute2Info routeVolume = new MediaRoute2Info.Builder(route) .setVolume(10).build(); assertNotEquals(route, routeVolume); MediaRoute2Info routeVolumeMax = new MediaRoute2Info.Builder(route) .setVolumeMax(30).build(); assertNotEquals(route, routeVolumeMax); MediaRoute2Info routeVolumeHandling = new MediaRoute2Info.Builder(route) .setVolumeHandling(PLAYBACK_VOLUME_FIXED).build(); assertNotEquals(route, routeVolumeHandling); MediaRoute2Info routeDeviceType = new MediaRoute2Info.Builder(route) .setVolume(DEVICE_TYPE_TV).build(); assertNotEquals(route, routeDeviceType); } @Test public void testControlVolumeWithRouter() throws Exception { Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_ALL); Loading
media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java +1 −18 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ 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; import static org.junit.Assert.assertTrue; Loading Loading @@ -124,20 +123,6 @@ public class MediaRouterManagerTest { clearCallbacks(); } //TODO: Move to a separate file @Test public void testMediaRoute2Info() { MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder("id", "name") .build(); MediaRoute2Info routeInfo2 = new MediaRoute2Info.Builder(routeInfo1).build(); MediaRoute2Info routeInfo3 = new MediaRoute2Info.Builder(routeInfo1) .setClientPackageName(mPackageName).build(); assertEquals(routeInfo1, routeInfo2); assertNotEquals(routeInfo1, routeInfo3); } /** * Tests if routes are added correctly when a new callback is registered. */ Loading Loading @@ -177,8 +162,6 @@ public class MediaRouterManagerTest { } }); //TODO: Figure out a more proper way to test. // (Control requests shouldn't be used in this way.) mRouter2.sendControlRequest(routes.get(ROUTE_ID2), new Intent(ACTION_REMOVE_ROUTE)); assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } Loading