From 1c888e2dbb51b0e3c3eaf8d52ea11ee5cc78b990 Mon Sep 17 00:00:00 2001 From: Hyundo Moon Date: Sun, 15 Mar 2020 19:46:41 +0900 Subject: Rename SampleMediaRoute2ProviderService to StubMediaRoute2ProviderService Bug: 151538499 Test: atest mediaroutertest Change-Id: I1467acf7482ac5421b800281e367353f08358eab --- media/tests/MediaRouter/AndroidManifest.xml | 2 +- .../mediaroutertest/MediaRouter2ManagerTest.java | 30 +- .../SampleMediaRoute2ProviderService.java | 370 --------------------- .../StubMediaRoute2ProviderService.java | 370 +++++++++++++++++++++ 4 files changed, 386 insertions(+), 386 deletions(-) delete mode 100644 media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java create mode 100644 media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml index 95465007d5ea..d9806f3cbb1d 100644 --- a/media/tests/MediaRouter/AndroidManifest.xml +++ b/media/tests/MediaRouter/AndroidManifest.xml @@ -19,7 +19,7 @@ - diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java index 230b9e4bfaad..a97baafac992 100644 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java @@ -22,16 +22,16 @@ import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE; import static android.media.MediaRoute2ProviderService.REASON_REJECTED; import static android.media.MediaRoute2ProviderService.REQUEST_ID_NONE; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SAMPLE; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SPECIAL; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID1; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID2; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_FIXED_VOLUME; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_VARIABLE_VOLUME; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_NAME2; -import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.VOLUME_MAX; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.FEATURE_SAMPLE; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.FEATURE_SPECIAL; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID1; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID2; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_FIXED_VOLUME; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_VARIABLE_VOLUME; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_NAME2; +import static com.android.mediaroutertest.StubMediaRoute2ProviderService.VOLUME_MAX; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -115,7 +115,7 @@ public class MediaRouter2ManagerTest { // unregister callbacks clearCallbacks(); - SampleMediaRoute2ProviderService instance = SampleMediaRoute2ProviderService.getInstance(); + StubMediaRoute2ProviderService instance = StubMediaRoute2ProviderService.getInstance(); if (instance != null) { instance.setProxy(null); } @@ -161,8 +161,8 @@ public class MediaRouter2ManagerTest { MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2); - SampleMediaRoute2ProviderService sInstance = - SampleMediaRoute2ProviderService.getInstance(); + StubMediaRoute2ProviderService sInstance = + StubMediaRoute2ProviderService.getInstance(); assertNotNull(sInstance); sInstance.removeRoute(ROUTE_ID2); assertTrue(removedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); @@ -413,12 +413,12 @@ public class MediaRouter2ManagerTest { Map routes = waitAndGetRoutesWithManager(FEATURES_ALL); MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME); - SampleMediaRoute2ProviderService instance = SampleMediaRoute2ProviderService.getInstance(); + StubMediaRoute2ProviderService instance = StubMediaRoute2ProviderService.getInstance(); assertNotNull(instance); final List requestIds = new ArrayList<>(); final CountDownLatch onSetRouteVolumeLatch = new CountDownLatch(1); - instance.setProxy(new SampleMediaRoute2ProviderService.Proxy() { + instance.setProxy(new StubMediaRoute2ProviderService.Proxy() { @Override public void onSetRouteVolume(String routeId, int volume, long requestId) { requestIds.add(requestId); diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java deleted file mode 100644 index f05d8ad79dee..000000000000 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright 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 android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE; -import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; -import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Intent; -import android.media.MediaRoute2Info; -import android.media.MediaRoute2ProviderService; -import android.media.RoutingSessionInfo; -import android.os.Bundle; -import android.os.IBinder; -import android.text.TextUtils; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import javax.annotation.concurrent.GuardedBy; - -public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService { - private static final String TAG = "SampleMR2ProviderSvc"; - private static final Object sLock = new Object(); - - public static final String ROUTE_ID1 = "route_id1"; - public static final String ROUTE_NAME1 = "Sample Route 1"; - public static final String ROUTE_ID2 = "route_id2"; - public static final String ROUTE_NAME2 = "Sample Route 2"; - public static final String ROUTE_ID3_SESSION_CREATION_FAILED = - "route_id3_session_creation_failed"; - public static final String ROUTE_NAME3 = "Sample Route 3 - Session creation failed"; - public static final String ROUTE_ID4_TO_SELECT_AND_DESELECT = - "route_id4_to_select_and_deselect"; - public static final String ROUTE_NAME4 = "Sample Route 4 - Route to select and deselect"; - public static final String ROUTE_ID5_TO_TRANSFER_TO = "route_id5_to_transfer_to"; - public static final String ROUTE_NAME5 = "Sample Route 5 - Route to transfer to"; - - public static final String ROUTE_ID_SPECIAL_FEATURE = "route_special_feature"; - public static final String ROUTE_NAME_SPECIAL_FEATURE = "Special Feature Route"; - - public static final int VOLUME_MAX = 100; - public static final int SESSION_VOLUME_MAX = 50; - public static final int SESSION_VOLUME_INITIAL = 20; - 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 FEATURE_SAMPLE = - "com.android.mediarouteprovider.FEATURE_SAMPLE"; - public static final String FEATURE_SPECIAL = - "com.android.mediarouteprovider.FEATURE_SPECIAL"; - - Map mRoutes = new HashMap<>(); - Map mRouteIdToSessionId = new HashMap<>(); - private int mNextSessionId = 1000; - - @GuardedBy("sLock") - private static SampleMediaRoute2ProviderService sInstance; - private Proxy mProxy; - - private void initializeRoutes() { - MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1) - .addFeature(FEATURE_SAMPLE) - .setType(TYPE_REMOTE_TV) - .build(); - MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2) - .addFeature(FEATURE_SAMPLE) - .setType(TYPE_REMOTE_SPEAKER) - .build(); - MediaRoute2Info route3 = new MediaRoute2Info.Builder( - ROUTE_ID3_SESSION_CREATION_FAILED, ROUTE_NAME3) - .addFeature(FEATURE_SAMPLE) - .build(); - MediaRoute2Info route4 = new MediaRoute2Info.Builder( - ROUTE_ID4_TO_SELECT_AND_DESELECT, ROUTE_NAME4) - .addFeature(FEATURE_SAMPLE) - .build(); - MediaRoute2Info route5 = new MediaRoute2Info.Builder( - ROUTE_ID5_TO_TRANSFER_TO, ROUTE_NAME5) - .addFeature(FEATURE_SAMPLE) - .build(); - - MediaRoute2Info routeSpecial = - new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_FEATURE, ROUTE_NAME_SPECIAL_FEATURE) - .addFeature(FEATURE_SAMPLE) - .addFeature(FEATURE_SPECIAL) - .build(); - MediaRoute2Info fixedVolumeRoute = - new MediaRoute2Info.Builder(ROUTE_ID_FIXED_VOLUME, ROUTE_NAME_FIXED_VOLUME) - .addFeature(FEATURE_SAMPLE) - .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_FIXED) - .build(); - MediaRoute2Info variableVolumeRoute = - new MediaRoute2Info.Builder(ROUTE_ID_VARIABLE_VOLUME, ROUTE_NAME_VARIABLE_VOLUME) - .addFeature(FEATURE_SAMPLE) - .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE) - .setVolumeMax(VOLUME_MAX) - .build(); - - mRoutes.put(route1.getId(), route1); - mRoutes.put(route2.getId(), route2); - mRoutes.put(route3.getId(), route3); - mRoutes.put(route4.getId(), route4); - mRoutes.put(route5.getId(), route5); - - mRoutes.put(routeSpecial.getId(), routeSpecial); - mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute); - mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute); - } - - public static SampleMediaRoute2ProviderService getInstance() { - synchronized (sLock) { - return sInstance; - } - } - - /** - * Adds a route and publishes it. It could replace a route in the provider if - * they have the same route id. - */ - public void addRoute(@NonNull MediaRoute2Info route) { - Objects.requireNonNull(route, "route must not be null"); - mRoutes.put(route.getOriginalId(), route); - publishRoutes(); - } - - /** - * Removes a route and publishes it. - */ - public void removeRoute(@NonNull String routeId) { - Objects.requireNonNull(routeId, "routeId must not be null"); - MediaRoute2Info route = mRoutes.get(routeId); - if (route != null) { - mRoutes.remove(routeId); - publishRoutes(); - } - } - - @Override - public void onCreate() { - synchronized (sLock) { - sInstance = this; - } - initializeRoutes(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - synchronized (sLock) { - if (sInstance == this) { - sInstance = null; - } - } - } - - @Override - public IBinder onBind(Intent intent) { - publishRoutes(); - return super.onBind(intent); - } - - @Override - public void onSetRouteVolume(long requestId, String routeId, int volume) { - Proxy proxy = mProxy; - if (proxy != null) { - proxy.onSetRouteVolume(routeId, volume, requestId); - return; - } - - MediaRoute2Info route = mRoutes.get(routeId); - if (route == null) { - return; - } - volume = Math.max(0, Math.min(volume, route.getVolumeMax())); - mRoutes.put(routeId, new MediaRoute2Info.Builder(route) - .setVolume(volume) - .build()); - publishRoutes(); - } - - @Override - public void onSetSessionVolume(long requestId, String sessionId, int volume) { - RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); - if (sessionInfo == null) { - return; - } - volume = Math.max(0, Math.min(volume, sessionInfo.getVolumeMax())); - RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) - .setVolume(volume) - .build(); - notifySessionUpdated(newSessionInfo); - } - - @Override - public void onCreateSession(long requestId, String packageName, String routeId, - @Nullable Bundle sessionHints) { - MediaRoute2Info route = mRoutes.get(routeId); - if (route == null || TextUtils.equals(ROUTE_ID3_SESSION_CREATION_FAILED, routeId)) { - notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR); - return; - } - maybeDeselectRoute(routeId); - - final String sessionId = String.valueOf(mNextSessionId); - mNextSessionId++; - - mRoutes.put(routeId, new MediaRoute2Info.Builder(route) - .setClientPackageName(packageName) - .build()); - mRouteIdToSessionId.put(routeId, sessionId); - - RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(sessionId, packageName) - .addSelectedRoute(routeId) - .addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT) - .addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO) - .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) - .setVolumeMax(SESSION_VOLUME_MAX) - .setVolume(SESSION_VOLUME_INITIAL) - // Set control hints with given sessionHints - .setControlHints(sessionHints) - .build(); - notifySessionCreated(requestId, sessionInfo); - publishRoutes(); - } - - @Override - public void onReleaseSession(long requestId, String sessionId) { - RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); - if (sessionInfo == null) { - return; - } - - for (String routeId : sessionInfo.getSelectedRoutes()) { - mRouteIdToSessionId.remove(routeId); - MediaRoute2Info route = mRoutes.get(routeId); - if (route != null) { - mRoutes.put(routeId, new MediaRoute2Info.Builder(route) - .setClientPackageName(null) - .build()); - } - } - notifySessionReleased(sessionId); - publishRoutes(); - } - - @Override - public void onSelectRoute(long requestId, String sessionId, String routeId) { - RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); - MediaRoute2Info route = mRoutes.get(routeId); - if (route == null || sessionInfo == null) { - return; - } - maybeDeselectRoute(routeId); - - mRoutes.put(routeId, new MediaRoute2Info.Builder(route) - .setClientPackageName(sessionInfo.getClientPackageName()) - .build()); - mRouteIdToSessionId.put(routeId, sessionId); - - RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) - .addSelectedRoute(routeId) - .removeSelectableRoute(routeId) - .addDeselectableRoute(routeId) - .build(); - notifySessionUpdated(newSessionInfo); - } - - @Override - public void onDeselectRoute(long requestId, String sessionId, String routeId) { - RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); - MediaRoute2Info route = mRoutes.get(routeId); - - if (sessionInfo == null || route == null - || !sessionInfo.getSelectedRoutes().contains(routeId)) { - return; - } - - mRouteIdToSessionId.remove(routeId); - mRoutes.put(routeId, new MediaRoute2Info.Builder(route) - .setClientPackageName(null) - .build()); - - if (sessionInfo.getSelectedRoutes().size() == 1) { - notifySessionReleased(sessionId); - return; - } - - RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) - .removeSelectedRoute(routeId) - .addSelectableRoute(routeId) - .removeDeselectableRoute(routeId) - .build(); - notifySessionUpdated(newSessionInfo); - } - - @Override - public void onTransferToRoute(long requestId, String sessionId, String routeId) { - RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); - MediaRoute2Info route = mRoutes.get(routeId); - - if (sessionInfo == null || route == null) { - return; - } - - for (String selectedRouteId : sessionInfo.getSelectedRoutes()) { - mRouteIdToSessionId.remove(selectedRouteId); - MediaRoute2Info selectedRoute = mRoutes.get(selectedRouteId); - if (selectedRoute != null) { - mRoutes.put(selectedRouteId, new MediaRoute2Info.Builder(selectedRoute) - .setClientPackageName(null) - .build()); - } - } - - mRoutes.put(routeId, new MediaRoute2Info.Builder(route) - .setClientPackageName(sessionInfo.getClientPackageName()) - .build()); - mRouteIdToSessionId.put(routeId, sessionId); - - RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) - .clearSelectedRoutes() - .addSelectedRoute(routeId) - .removeDeselectableRoute(routeId) - .removeTransferableRoute(routeId) - .build(); - notifySessionUpdated(newSessionInfo); - publishRoutes(); - } - - void maybeDeselectRoute(String routeId) { - if (!mRouteIdToSessionId.containsKey(routeId)) { - return; - } - - String sessionId = mRouteIdToSessionId.get(routeId); - onDeselectRoute(REQUEST_ID_NONE, sessionId, routeId); - } - - void publishRoutes() { - notifyRoutes(mRoutes.values()); - } - - public void setProxy(@Nullable Proxy proxy) { - mProxy = proxy; - } - - public static class Proxy { - public void onSetRouteVolume(String routeId, int volume, long requestId) {} - } -} diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java new file mode 100644 index 000000000000..6d46ba582ddc --- /dev/null +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/StubMediaRoute2ProviderService.java @@ -0,0 +1,370 @@ +/* + * Copyright 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 android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE; +import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; +import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Intent; +import android.media.MediaRoute2Info; +import android.media.MediaRoute2ProviderService; +import android.media.RoutingSessionInfo; +import android.os.Bundle; +import android.os.IBinder; +import android.text.TextUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import javax.annotation.concurrent.GuardedBy; + +public class StubMediaRoute2ProviderService extends MediaRoute2ProviderService { + private static final String TAG = "SampleMR2ProviderSvc"; + private static final Object sLock = new Object(); + + public static final String ROUTE_ID1 = "route_id1"; + public static final String ROUTE_NAME1 = "Sample Route 1"; + public static final String ROUTE_ID2 = "route_id2"; + public static final String ROUTE_NAME2 = "Sample Route 2"; + public static final String ROUTE_ID3_SESSION_CREATION_FAILED = + "route_id3_session_creation_failed"; + public static final String ROUTE_NAME3 = "Sample Route 3 - Session creation failed"; + public static final String ROUTE_ID4_TO_SELECT_AND_DESELECT = + "route_id4_to_select_and_deselect"; + public static final String ROUTE_NAME4 = "Sample Route 4 - Route to select and deselect"; + public static final String ROUTE_ID5_TO_TRANSFER_TO = "route_id5_to_transfer_to"; + public static final String ROUTE_NAME5 = "Sample Route 5 - Route to transfer to"; + + public static final String ROUTE_ID_SPECIAL_FEATURE = "route_special_feature"; + public static final String ROUTE_NAME_SPECIAL_FEATURE = "Special Feature Route"; + + public static final int VOLUME_MAX = 100; + public static final int SESSION_VOLUME_MAX = 50; + public static final int SESSION_VOLUME_INITIAL = 20; + 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 FEATURE_SAMPLE = + "com.android.mediarouteprovider.FEATURE_SAMPLE"; + public static final String FEATURE_SPECIAL = + "com.android.mediarouteprovider.FEATURE_SPECIAL"; + + Map mRoutes = new HashMap<>(); + Map mRouteIdToSessionId = new HashMap<>(); + private int mNextSessionId = 1000; + + @GuardedBy("sLock") + private static StubMediaRoute2ProviderService sInstance; + private Proxy mProxy; + + private void initializeRoutes() { + MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1) + .addFeature(FEATURE_SAMPLE) + .setType(TYPE_REMOTE_TV) + .build(); + MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2) + .addFeature(FEATURE_SAMPLE) + .setType(TYPE_REMOTE_SPEAKER) + .build(); + MediaRoute2Info route3 = new MediaRoute2Info.Builder( + ROUTE_ID3_SESSION_CREATION_FAILED, ROUTE_NAME3) + .addFeature(FEATURE_SAMPLE) + .build(); + MediaRoute2Info route4 = new MediaRoute2Info.Builder( + ROUTE_ID4_TO_SELECT_AND_DESELECT, ROUTE_NAME4) + .addFeature(FEATURE_SAMPLE) + .build(); + MediaRoute2Info route5 = new MediaRoute2Info.Builder( + ROUTE_ID5_TO_TRANSFER_TO, ROUTE_NAME5) + .addFeature(FEATURE_SAMPLE) + .build(); + + MediaRoute2Info routeSpecial = + new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_FEATURE, ROUTE_NAME_SPECIAL_FEATURE) + .addFeature(FEATURE_SAMPLE) + .addFeature(FEATURE_SPECIAL) + .build(); + MediaRoute2Info fixedVolumeRoute = + new MediaRoute2Info.Builder(ROUTE_ID_FIXED_VOLUME, ROUTE_NAME_FIXED_VOLUME) + .addFeature(FEATURE_SAMPLE) + .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_FIXED) + .build(); + MediaRoute2Info variableVolumeRoute = + new MediaRoute2Info.Builder(ROUTE_ID_VARIABLE_VOLUME, ROUTE_NAME_VARIABLE_VOLUME) + .addFeature(FEATURE_SAMPLE) + .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE) + .setVolumeMax(VOLUME_MAX) + .build(); + + mRoutes.put(route1.getId(), route1); + mRoutes.put(route2.getId(), route2); + mRoutes.put(route3.getId(), route3); + mRoutes.put(route4.getId(), route4); + mRoutes.put(route5.getId(), route5); + + mRoutes.put(routeSpecial.getId(), routeSpecial); + mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute); + mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute); + } + + public static StubMediaRoute2ProviderService getInstance() { + synchronized (sLock) { + return sInstance; + } + } + + /** + * Adds a route and publishes it. It could replace a route in the provider if + * they have the same route id. + */ + public void addRoute(@NonNull MediaRoute2Info route) { + Objects.requireNonNull(route, "route must not be null"); + mRoutes.put(route.getOriginalId(), route); + publishRoutes(); + } + + /** + * Removes a route and publishes it. + */ + public void removeRoute(@NonNull String routeId) { + Objects.requireNonNull(routeId, "routeId must not be null"); + MediaRoute2Info route = mRoutes.get(routeId); + if (route != null) { + mRoutes.remove(routeId); + publishRoutes(); + } + } + + @Override + public void onCreate() { + synchronized (sLock) { + sInstance = this; + } + initializeRoutes(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + synchronized (sLock) { + if (sInstance == this) { + sInstance = null; + } + } + } + + @Override + public IBinder onBind(Intent intent) { + publishRoutes(); + return super.onBind(intent); + } + + @Override + public void onSetRouteVolume(long requestId, String routeId, int volume) { + Proxy proxy = mProxy; + if (proxy != null) { + proxy.onSetRouteVolume(routeId, volume, requestId); + return; + } + + MediaRoute2Info route = mRoutes.get(routeId); + if (route == null) { + return; + } + volume = Math.max(0, Math.min(volume, route.getVolumeMax())); + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) + .setVolume(volume) + .build()); + publishRoutes(); + } + + @Override + public void onSetSessionVolume(long requestId, String sessionId, int volume) { + RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); + if (sessionInfo == null) { + return; + } + volume = Math.max(0, Math.min(volume, sessionInfo.getVolumeMax())); + RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) + .setVolume(volume) + .build(); + notifySessionUpdated(newSessionInfo); + } + + @Override + public void onCreateSession(long requestId, String packageName, String routeId, + @Nullable Bundle sessionHints) { + MediaRoute2Info route = mRoutes.get(routeId); + if (route == null || TextUtils.equals(ROUTE_ID3_SESSION_CREATION_FAILED, routeId)) { + notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR); + return; + } + maybeDeselectRoute(routeId); + + final String sessionId = String.valueOf(mNextSessionId); + mNextSessionId++; + + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) + .setClientPackageName(packageName) + .build()); + mRouteIdToSessionId.put(routeId, sessionId); + + RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(sessionId, packageName) + .addSelectedRoute(routeId) + .addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT) + .addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO) + .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) + .setVolumeMax(SESSION_VOLUME_MAX) + .setVolume(SESSION_VOLUME_INITIAL) + // Set control hints with given sessionHints + .setControlHints(sessionHints) + .build(); + notifySessionCreated(requestId, sessionInfo); + publishRoutes(); + } + + @Override + public void onReleaseSession(long requestId, String sessionId) { + RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); + if (sessionInfo == null) { + return; + } + + for (String routeId : sessionInfo.getSelectedRoutes()) { + mRouteIdToSessionId.remove(routeId); + MediaRoute2Info route = mRoutes.get(routeId); + if (route != null) { + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) + .setClientPackageName(null) + .build()); + } + } + notifySessionReleased(sessionId); + publishRoutes(); + } + + @Override + public void onSelectRoute(long requestId, String sessionId, String routeId) { + RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); + MediaRoute2Info route = mRoutes.get(routeId); + if (route == null || sessionInfo == null) { + return; + } + maybeDeselectRoute(routeId); + + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) + .setClientPackageName(sessionInfo.getClientPackageName()) + .build()); + mRouteIdToSessionId.put(routeId, sessionId); + + RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) + .addSelectedRoute(routeId) + .removeSelectableRoute(routeId) + .addDeselectableRoute(routeId) + .build(); + notifySessionUpdated(newSessionInfo); + } + + @Override + public void onDeselectRoute(long requestId, String sessionId, String routeId) { + RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); + MediaRoute2Info route = mRoutes.get(routeId); + + if (sessionInfo == null || route == null + || !sessionInfo.getSelectedRoutes().contains(routeId)) { + return; + } + + mRouteIdToSessionId.remove(routeId); + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) + .setClientPackageName(null) + .build()); + + if (sessionInfo.getSelectedRoutes().size() == 1) { + notifySessionReleased(sessionId); + return; + } + + RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) + .removeSelectedRoute(routeId) + .addSelectableRoute(routeId) + .removeDeselectableRoute(routeId) + .build(); + notifySessionUpdated(newSessionInfo); + } + + @Override + public void onTransferToRoute(long requestId, String sessionId, String routeId) { + RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); + MediaRoute2Info route = mRoutes.get(routeId); + + if (sessionInfo == null || route == null) { + return; + } + + for (String selectedRouteId : sessionInfo.getSelectedRoutes()) { + mRouteIdToSessionId.remove(selectedRouteId); + MediaRoute2Info selectedRoute = mRoutes.get(selectedRouteId); + if (selectedRoute != null) { + mRoutes.put(selectedRouteId, new MediaRoute2Info.Builder(selectedRoute) + .setClientPackageName(null) + .build()); + } + } + + mRoutes.put(routeId, new MediaRoute2Info.Builder(route) + .setClientPackageName(sessionInfo.getClientPackageName()) + .build()); + mRouteIdToSessionId.put(routeId, sessionId); + + RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) + .clearSelectedRoutes() + .addSelectedRoute(routeId) + .removeDeselectableRoute(routeId) + .removeTransferableRoute(routeId) + .build(); + notifySessionUpdated(newSessionInfo); + publishRoutes(); + } + + void maybeDeselectRoute(String routeId) { + if (!mRouteIdToSessionId.containsKey(routeId)) { + return; + } + + String sessionId = mRouteIdToSessionId.get(routeId); + onDeselectRoute(REQUEST_ID_NONE, sessionId, routeId); + } + + void publishRoutes() { + notifyRoutes(mRoutes.values()); + } + + public void setProxy(@Nullable Proxy proxy) { + mProxy = proxy; + } + + public static class Proxy { + public void onSetRouteVolume(String routeId, int volume, long requestId) {} + } +} -- cgit v1.2.3-59-g8ed1b