blob: 638a842e4e5f14491e13d60b693eea4e7b2834e9 [file] [log] [blame]
Kyunglyul Hyund51666d2019-04-11 04:08:40 +00001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.mediaroutertest;
18
Hyundo Moon5de706f2020-02-03 20:16:33 +090019import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
Kyunglyul Hyuna3be2de2020-06-02 17:42:36 +090020import static android.media.MediaRoute2Info.FEATURE_REMOTE_PLAYBACK;
Kyunglyul Hyun9b10a642019-10-08 15:29:23 +090021import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
22import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
Hyundo Moon0fa60e82020-02-14 11:44:45 +090023import static android.media.MediaRoute2ProviderService.REASON_REJECTED;
24import static android.media.MediaRoute2ProviderService.REQUEST_ID_NONE;
Kyunglyul Hyun9b10a642019-10-08 15:29:23 +090025
Hyundo Moon1c888e22020-03-15 19:46:41 +090026import static com.android.mediaroutertest.StubMediaRoute2ProviderService.FEATURE_SAMPLE;
27import static com.android.mediaroutertest.StubMediaRoute2ProviderService.FEATURE_SPECIAL;
28import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID1;
29import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID2;
Kyunglyul Hyun45512bb2020-05-08 15:21:13 +090030import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
Hyundo Moon1c888e22020-03-15 19:46:41 +090031import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
Kyunglyul Hyun8df5fb62020-06-03 16:52:04 +090032import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID6_TO_BE_IGNORED;
Hyundo Moon1c888e22020-03-15 19:46:41 +090033import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_FIXED_VOLUME;
34import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
35import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_ID_VARIABLE_VOLUME;
36import static com.android.mediaroutertest.StubMediaRoute2ProviderService.ROUTE_NAME2;
37import static com.android.mediaroutertest.StubMediaRoute2ProviderService.VOLUME_MAX;
Hyundo Moon5de706f2020-02-03 20:16:33 +090038
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090039import static org.junit.Assert.assertEquals;
Hyundo Moon0fa60e82020-02-14 11:44:45 +090040import static org.junit.Assert.assertFalse;
Kyunglyul Hyun23b3aaa2019-08-06 11:17:16 +090041import static org.junit.Assert.assertNotNull;
Kyunglyul Hyun350d7b42020-04-17 23:09:08 +090042import static org.junit.Assert.assertNull;
Kyunglyul Hyun7af73012019-10-11 20:01:30 +090043import static org.junit.Assert.assertTrue;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000044
45import android.content.Context;
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090046import android.media.MediaRoute2Info;
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +090047import android.media.MediaRouter2;
Hyundo Moon63a05402019-12-19 20:13:56 +090048import android.media.MediaRouter2.RouteCallback;
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +090049import android.media.MediaRouter2.TransferCallback;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000050import android.media.MediaRouter2Manager;
Kyunglyul Hyun5161b372020-02-05 18:45:35 +090051import android.media.MediaRouter2Utils;
Kyunglyul Hyun616096e2020-01-09 16:15:03 +090052import android.media.RouteDiscoveryPreference;
Kyunglyul Hyunc6583832020-01-17 11:11:46 +000053import android.media.RoutingSessionInfo;
Kyunglyul Hyunf0eb51b2020-04-14 19:56:16 +090054import android.os.Bundle;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000055import android.support.test.InstrumentationRegistry;
Kyunglyul Hyun8df5fb62020-06-03 16:52:04 +090056import android.support.test.filters.LargeTest;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000057import android.support.test.filters.SmallTest;
58import android.support.test.runner.AndroidJUnit4;
Kyunglyul Hyun13bc1052019-05-31 17:00:36 +090059import android.text.TextUtils;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000060
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +090061import org.junit.After;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000062import org.junit.Before;
63import org.junit.Test;
64import org.junit.runner.RunWith;
65
66import java.util.ArrayList;
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090067import java.util.HashMap;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000068import java.util.List;
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090069import java.util.Map;
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +090070import java.util.concurrent.CountDownLatch;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000071import java.util.concurrent.Executor;
Kyunglyul Hyund1f0b6e2019-08-06 11:17:16 +090072import java.util.concurrent.Executors;
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +090073import java.util.concurrent.TimeUnit;
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +090074import java.util.function.Predicate;
Kyunglyul Hyun45512bb2020-05-08 15:21:13 +090075import java.util.stream.Collectors;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000076
77@RunWith(AndroidJUnit4.class)
78@SmallTest
Hyundo Moone90a28e2020-02-14 10:43:51 +090079public class MediaRouter2ManagerTest {
80 private static final String TAG = "MediaRouter2ManagerTest";
Hyundo Moon0fa60e82020-02-14 11:44:45 +090081 private static final int WAIT_TIME_MS = 2000;
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090082 private static final int TIMEOUT_MS = 5000;
Kyunglyul Hyunf0eb51b2020-04-14 19:56:16 +090083 private static final String TEST_KEY = "test_key";
84 private static final String TEST_VALUE = "test_value";
Kyunglyul Hyuna3be2de2020-06-02 17:42:36 +090085 private static final String TEST_ID_UNKNOWN = "id_unknown";
86 private static final String TEST_NAME_UNKNOWN = "unknown";
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000087
88 private Context mContext;
89 private MediaRouter2Manager mManager;
Kyunglyul Hyun2f43fd62019-09-16 18:47:52 +090090 private MediaRouter2 mRouter2;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000091 private Executor mExecutor;
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090092 private String mPackageName;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000093
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +090094 private final List<MediaRouter2Manager.Callback> mManagerCallbacks = new ArrayList<>();
Kyunglyul Hyun138246e2020-01-02 18:19:52 +090095 private final List<RouteCallback> mRouteCallbacks = new ArrayList<>();
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +090096 private final List<MediaRouter2.TransferCallback> mTransferCallbacks = new ArrayList<>();
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +090097
Kyunglyul Hyun616096e2020-01-09 16:15:03 +090098 public static final List<String> FEATURES_ALL = new ArrayList();
99 public static final List<String> FEATURES_SPECIAL = new ArrayList();
100 private static final List<String> FEATURES_LIVE_AUDIO = new ArrayList<>();
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900101
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000102 static {
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900103 FEATURES_ALL.add(FEATURE_SAMPLE);
104 FEATURES_ALL.add(FEATURE_SPECIAL);
105 FEATURES_ALL.add(FEATURE_LIVE_AUDIO);
Kyunglyul Hyune23e5ed2019-07-15 16:06:26 +0900106
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900107 FEATURES_SPECIAL.add(FEATURE_SPECIAL);
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +0000108
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900109 FEATURES_LIVE_AUDIO.add(FEATURE_LIVE_AUDIO);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000110 }
111
112 @Before
113 public void setUp() throws Exception {
114 mContext = InstrumentationRegistry.getTargetContext();
115 mManager = MediaRouter2Manager.getInstance(mContext);
Kyunglyul Hyun2f43fd62019-09-16 18:47:52 +0900116 mRouter2 = MediaRouter2.getInstance(mContext);
Hyundo Moon0f78fc62020-06-01 14:50:32 +0900117 // If we need to support thread pool executors, change this to thread pool executor.
Kyunglyul Hyund1f0b6e2019-08-06 11:17:16 +0900118 mExecutor = Executors.newSingleThreadExecutor();
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900119 mPackageName = mContext.getPackageName();
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900120 }
121
122 @After
123 public void tearDown() {
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000124 // order matters (callbacks should be cleared at the last)
125 releaseAllSessions();
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900126 // unregister callbacks
127 clearCallbacks();
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900128
Hyundo Moon1c888e22020-03-15 19:46:41 +0900129 StubMediaRoute2ProviderService instance = StubMediaRoute2ProviderService.getInstance();
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900130 if (instance != null) {
131 instance.setProxy(null);
132 }
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900133 }
134
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000135 @Test
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900136 public void testOnRoutesRemovedAndAdded() throws Exception {
Hyundo Moon899535c2020-02-28 17:47:37 +0900137 RouteCallback routeCallback = new RouteCallback() {};
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900138 mRouteCallbacks.add(routeCallback);
139 mRouter2.registerRouteCallback(mExecutor, routeCallback,
140 new RouteDiscoveryPreference.Builder(FEATURES_ALL, true).build());
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000141
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900142 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900143
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900144 CountDownLatch removedLatch = new CountDownLatch(1);
145 CountDownLatch addedLatch = new CountDownLatch(1);
146
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900147 addManagerCallback(new MediaRouter2Manager.Callback() {
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900148 @Override
149 public void onRoutesRemoved(List<MediaRoute2Info> routes) {
150 assertTrue(routes.size() > 0);
151 for (MediaRoute2Info route : routes) {
Hyundo Moon5de706f2020-02-03 20:16:33 +0900152 if (route.getOriginalId().equals(ROUTE_ID2)
153 && route.getName().equals(ROUTE_NAME2)) {
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900154 removedLatch.countDown();
155 }
156 }
157 }
158 @Override
159 public void onRoutesAdded(List<MediaRoute2Info> routes) {
160 assertTrue(routes.size() > 0);
161 if (removedLatch.getCount() > 0) {
162 return;
163 }
164 for (MediaRoute2Info route : routes) {
165 if (route.getOriginalId().equals(ROUTE_ID2)
166 && route.getName().equals(ROUTE_NAME2)) {
167 addedLatch.countDown();
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900168 }
169 }
170 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900171 });
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +0900172
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900173 MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2);
Kyunglyul Hyun350d7b42020-04-17 23:09:08 +0900174 assertNotNull(routeToRemove);
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900175
Hyundo Moon1c888e22020-03-15 19:46:41 +0900176 StubMediaRoute2ProviderService sInstance =
177 StubMediaRoute2ProviderService.getInstance();
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900178 assertNotNull(sInstance);
179 sInstance.removeRoute(ROUTE_ID2);
180 assertTrue(removedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Kyunglyul Hyunc943f212020-02-14 17:58:23 +0900181
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900182 sInstance.addRoute(routeToRemove);
183 assertTrue(addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Kyunglyul Hyun2f43fd62019-09-16 18:47:52 +0900184 }
185
Kyunglyul Hyun350d7b42020-04-17 23:09:08 +0900186 @Test
187 public void testGetRoutes_removedRoute_returnsCorrectRoutes() throws Exception {
188 CountDownLatch addedLatch = new CountDownLatch(1);
189 CountDownLatch removedLatch = new CountDownLatch(1);
190
191 RouteCallback routeCallback = new RouteCallback() {
192 // Used to ensure the removed route is added.
193 @Override
194 public void onRoutesAdded(List<MediaRoute2Info> routes) {
195 if (removedLatch.getCount() > 0) {
196 return;
197 }
198 addedLatch.countDown();
199 }
200
201 @Override
202 public void onRoutesRemoved(List<MediaRoute2Info> routes) {
203 removedLatch.countDown();
204 }
205 };
206
207 mRouter2.registerRouteCallback(mExecutor, routeCallback,
208 new RouteDiscoveryPreference.Builder(FEATURES_ALL, true).build());
209 mRouteCallbacks.add(routeCallback);
210
211 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
212 MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2);
213 assertNotNull(routeToRemove);
214
215 StubMediaRoute2ProviderService sInstance =
216 StubMediaRoute2ProviderService.getInstance();
217 assertNotNull(sInstance);
218 sInstance.removeRoute(ROUTE_ID2);
219
220 // Wait until the route is removed.
221 assertTrue(removedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
222
223 Map<String, MediaRoute2Info> newRoutes = waitAndGetRoutesWithManager(FEATURES_ALL);
224 assertNull(newRoutes.get(ROUTE_ID2));
225
226 // Revert the removal.
227 sInstance.addRoute(routeToRemove);
228 assertTrue(addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
229 mRouter2.unregisterRouteCallback(routeCallback);
230 }
231
Kyunglyul Hyun2f43fd62019-09-16 18:47:52 +0900232 /**
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900233 * Tests if we get proper routes for application that has special route feature.
Kyunglyul Hyun2f43fd62019-09-16 18:47:52 +0900234 */
235 @Test
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900236 public void testRouteFeatures() throws Exception {
237 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_SPECIAL);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000238
Kyunglyul Hyun96d36ce2020-01-29 19:59:33 +0900239 int routeCount = 0;
240 for (MediaRoute2Info route : routes.values()) {
241 if (!route.isSystemRoute()) {
242 routeCount++;
243 }
244 }
245
246 assertEquals(1, routeCount);
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900247 assertNotNull(routes.get(ROUTE_ID_SPECIAL_FEATURE));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000248 }
Kyunglyul Hyun13bc1052019-05-31 17:00:36 +0900249
Kyunglyul Hyun23b3aaa2019-08-06 11:17:16 +0900250 /**
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900251 * Tests if MR2.SessionCallback.onSessionCreated is called
252 * when a route is selected from MR2Manager.
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900253 */
Colin Cross0f782162019-12-18 17:16:36 -0800254 @Test
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900255 public void testRouterOnSessionCreated() throws Exception {
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900256 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900257
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900258 CountDownLatch latch = new CountDownLatch(1);
Kyunglyul Hyun13bc1052019-05-31 17:00:36 +0900259
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900260 addManagerCallback(new MediaRouter2Manager.Callback());
Hyundo Moon899535c2020-02-28 17:47:37 +0900261 addRouterCallback(new MediaRouter2.RouteCallback() {});
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900262 addTransferCallback(new MediaRouter2.TransferCallback() {
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900263 @Override
Kyunglyul Hyunf4552af2020-03-20 23:25:11 +0900264 public void onTransfer(MediaRouter2.RoutingController oldController,
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900265 MediaRouter2.RoutingController newController) {
266 if (newController == null) {
267 return;
268 }
269 if (createRouteMap(newController.getSelectedRoutes()).containsKey(ROUTE_ID1)) {
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900270 latch.countDown();
271 }
272 }
273 });
Kyunglyul Hyun13bc1052019-05-31 17:00:36 +0900274
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900275 MediaRoute2Info routeToSelect = routes.get(ROUTE_ID1);
Kyunglyul Hyun23b3aaa2019-08-06 11:17:16 +0900276 assertNotNull(routeToSelect);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900277
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000278 mManager.selectRoute(mPackageName, routeToSelect);
279 assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Hyundo Moon67c41fd2020-01-17 14:22:42 +0900280 assertEquals(2, mManager.getActiveSessions().size());
Kyunglyul Hyun13bc1052019-05-31 17:00:36 +0900281 }
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900282
Colin Cross0f782162019-12-18 17:16:36 -0800283 @Test
Kyunglyul Hyunfe7b5b12020-06-04 20:17:59 +0900284 public void testGetRoutingSessions() throws Exception {
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900285 CountDownLatch latch = new CountDownLatch(1);
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900286
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900287 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Kyunglyul Hyunfe7b5b12020-06-04 20:17:59 +0900288 MediaRoute2Info routeToSelect = routes.get(ROUTE_ID1);
289
Hyundo Moon899535c2020-02-28 17:47:37 +0900290 addRouterCallback(new RouteCallback() {});
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900291 addManagerCallback(new MediaRouter2Manager.Callback() {
292 @Override
Kyunglyul Hyunf064dcae2020-03-06 22:59:14 +0900293 public void onTransferred(RoutingSessionInfo oldSessionInfo,
294 RoutingSessionInfo newSessionInfo) {
295 if (TextUtils.equals(mPackageName, newSessionInfo.getClientPackageName())
Kyunglyul Hyunfe7b5b12020-06-04 20:17:59 +0900296 && newSessionInfo.getSelectedRoutes().contains(routeToSelect.getId())) {
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900297 latch.countDown();
298 }
299 }
300 });
301
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900302 assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900303
Kyunglyul Hyunfe7b5b12020-06-04 20:17:59 +0900304 mManager.selectRoute(mPackageName, routeToSelect);
305 assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900306
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900307 List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900308 assertEquals(2, sessions.size());
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000309
Kyunglyul Hyuna3365d72020-02-20 13:46:45 +0900310 RoutingSessionInfo sessionInfo = sessions.get(1);
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900311 awaitOnRouteChangedManager(
Kyunglyul Hyuna3365d72020-02-20 13:46:45 +0900312 () -> mManager.releaseSession(sessionInfo),
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900313 ROUTE_ID1,
314 route -> TextUtils.equals(route.getClientPackageName(), null));
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900315 assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
Kyunglyul Hyun86998f42019-12-12 17:50:48 +0900316 }
317
Kyunglyul Hyuna3be2de2020-06-02 17:42:36 +0900318 @Test
319 public void testTransfer_unknownRoute_fail() throws Exception {
320 addRouterCallback(new RouteCallback() {});
321
322 CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
323 CountDownLatch onTransferFailedLatch = new CountDownLatch(1);
324
325 addManagerCallback(new MediaRouter2Manager.Callback() {
326 @Override
327 public void onTransferred(RoutingSessionInfo oldSessionInfo,
328 RoutingSessionInfo newSessionInfo) {
329 assertNotNull(newSessionInfo);
330 onSessionCreatedLatch.countDown();
331 }
332 @Override
333 public void onTransferFailed(RoutingSessionInfo session, MediaRoute2Info route) {
334 onTransferFailedLatch.countDown();
335 }
336 });
337
338 MediaRoute2Info unknownRoute =
339 new MediaRoute2Info.Builder(TEST_ID_UNKNOWN, TEST_NAME_UNKNOWN)
340 .addFeature(FEATURE_REMOTE_PLAYBACK)
341 .build();
342
343 mManager.transfer(mManager.getSystemRoutingSession(), unknownRoute);
344 assertFalse(onSessionCreatedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
345 assertTrue(onTransferFailedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
346 }
347
Kyunglyul Hyunfe7b5b12020-06-04 20:17:59 +0900348 @Test
349 public void testRouterRelease_managerGetRoutingSessions() throws Exception {
350 CountDownLatch transferLatch = new CountDownLatch(1);
351 CountDownLatch releaseLatch = new CountDownLatch(1);
352
353 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
354 MediaRoute2Info routeToSelect = routes.get(ROUTE_ID1);
355 assertNotNull(routeToSelect);
356
357 addRouterCallback(new RouteCallback() {});
358 addManagerCallback(new MediaRouter2Manager.Callback() {
359 @Override
360 public void onTransferred(RoutingSessionInfo oldSessionInfo,
361 RoutingSessionInfo newSessionInfo) {
362 if (TextUtils.equals(mPackageName, newSessionInfo.getClientPackageName())
363 && newSessionInfo.getSelectedRoutes().contains(routeToSelect.getId())) {
364 transferLatch.countDown();
365 }
366 }
367 @Override
368 public void onSessionReleased(RoutingSessionInfo session) {
369 releaseLatch.countDown();
370 }
371 });
372
373 assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
374 assertEquals(1, mRouter2.getControllers().size());
375
376 mManager.transfer(mManager.getRoutingSessions(mPackageName).get(0), routeToSelect);
377 assertTrue(transferLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
378
379 assertEquals(2, mManager.getRoutingSessions(mPackageName).size());
380 assertEquals(2, mRouter2.getControllers().size());
381 mRouter2.getControllers().get(1).release();
382
383 assertTrue(releaseLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
384
385 assertEquals(1, mRouter2.getControllers().size());
386 assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
387 }
388
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900389 /**
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000390 * Tests select, transfer, release of routes of a provider
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900391 */
Colin Cross0f782162019-12-18 17:16:36 -0800392 @Test
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000393 public void testSelectAndTransferAndRelease() throws Exception {
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900394 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Hyundo Moon899535c2020-02-28 17:47:37 +0900395 addRouterCallback(new RouteCallback() {});
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900396
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000397 CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
398
399 addManagerCallback(new MediaRouter2Manager.Callback() {
400 @Override
Kyunglyul Hyunf064dcae2020-03-06 22:59:14 +0900401 public void onTransferred(RoutingSessionInfo oldSessionInfo,
402 RoutingSessionInfo newSessionInfo) {
403 assertNotNull(newSessionInfo);
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000404 onSessionCreatedLatch.countDown();
405 }
406 });
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900407 awaitOnRouteChangedManager(
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900408 () -> mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1)),
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900409 ROUTE_ID1,
410 route -> TextUtils.equals(route.getClientPackageName(), mPackageName));
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000411 assertTrue(onSessionCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
412
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900413 List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000414
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900415 assertEquals(2, sessions.size());
Kyunglyul Hyuna3365d72020-02-20 13:46:45 +0900416 RoutingSessionInfo sessionInfo = sessions.get(1);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900417
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900418 awaitOnRouteChangedManager(
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000419 () -> mManager.selectRoute(mPackageName, routes.get(ROUTE_ID5_TO_TRANSFER_TO)),
420 ROUTE_ID5_TO_TRANSFER_TO,
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900421 route -> TextUtils.equals(route.getClientPackageName(), mPackageName));
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900422
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900423 awaitOnRouteChangedManager(
Kyunglyul Hyuna3365d72020-02-20 13:46:45 +0900424 () -> mManager.releaseSession(sessionInfo),
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000425 ROUTE_ID5_TO_TRANSFER_TO,
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900426 route -> TextUtils.equals(route.getClientPackageName(), null));
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900427 }
428
Kyunglyul Hyun9b10a642019-10-08 15:29:23 +0900429 @Test
Kyunglyul Hyun8df5fb62020-06-03 16:52:04 +0900430 @LargeTest
431 public void testTransfer_ignored_fails() throws Exception {
432 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
433 addRouterCallback(new RouteCallback() {});
434
435 CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
436 CountDownLatch onFailedLatch = new CountDownLatch(1);
437
438 addManagerCallback(new MediaRouter2Manager.Callback() {
439 @Override
440 public void onTransferred(RoutingSessionInfo oldSessionInfo,
441 RoutingSessionInfo newSessionInfo) {
442 onSessionCreatedLatch.countDown();
443 }
444 @Override
445 public void onTransferFailed(RoutingSessionInfo session, MediaRoute2Info route) {
446 onFailedLatch.countDown();
447 }
448 });
449
450 List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
451 RoutingSessionInfo targetSession = sessions.get(sessions.size() - 1);
452 mManager.transfer(targetSession, routes.get(ROUTE_ID6_TO_BE_IGNORED));
453
454 assertFalse(onSessionCreatedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
455 assertTrue(onFailedLatch.await(MediaRouter2Manager.TRANSFER_TIMEOUT_MS,
456 TimeUnit.MILLISECONDS));
457 }
458 @Test
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900459 public void testSetSystemRouteVolume() throws Exception {
460 // ensure client
461 addManagerCallback(new MediaRouter2Manager.Callback());
462 String selectedSystemRouteId =
463 MediaRouter2Utils.getOriginalId(
464 mManager.getActiveSessions().get(0).getSelectedRoutes().get(0));
Kyunglyul Hyunf55befb2020-02-20 19:57:43 +0900465 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900466 MediaRoute2Info volRoute = routes.get(selectedSystemRouteId);
467 assertNotNull(volRoute);
468
469 int originalVolume = volRoute.getVolume();
470 int targetVolume = originalVolume == volRoute.getVolumeMax()
471 ? originalVolume - 1 : originalVolume + 1;
472
473 awaitOnRouteChangedManager(
474 () -> mManager.setRouteVolume(volRoute, targetVolume),
475 selectedSystemRouteId,
476 (route -> route.getVolume() == targetVolume));
477
478 awaitOnRouteChangedManager(
479 () -> mManager.setRouteVolume(volRoute, originalVolume),
480 selectedSystemRouteId,
481 (route -> route.getVolume() == originalVolume));
482 }
483
484 @Test
485 public void testSetRouteVolume() throws Exception {
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900486 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900487 MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
488
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900489 int originalVolume = volRoute.getVolume();
Hyundo Moon891c94f2020-02-04 10:29:50 +0900490 int targetVolume = originalVolume == volRoute.getVolumeMax()
491 ? originalVolume - 1 : originalVolume + 1;
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900492
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900493 awaitOnRouteChangedManager(
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900494 () -> mManager.setRouteVolume(volRoute, targetVolume),
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900495 ROUTE_ID_VARIABLE_VOLUME,
Hyundo Moon891c94f2020-02-04 10:29:50 +0900496 (route -> route.getVolume() == targetVolume));
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900497
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900498 awaitOnRouteChangedManager(
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900499 () -> mManager.setRouteVolume(volRoute, originalVolume),
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900500 ROUTE_ID_VARIABLE_VOLUME,
501 (route -> route.getVolume() == originalVolume));
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900502 }
503
504 @Test
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900505 public void testSetSessionVolume() throws Exception {
506 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Hyundo Moon899535c2020-02-28 17:47:37 +0900507 addRouterCallback(new RouteCallback() {});
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900508
509 CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
510 CountDownLatch volumeChangedLatch = new CountDownLatch(2);
511
512 // create a controller
513 addManagerCallback(new MediaRouter2Manager.Callback() {
514 @Override
Kyunglyul Hyunf064dcae2020-03-06 22:59:14 +0900515 public void onTransferred(RoutingSessionInfo oldSessionInfo,
516 RoutingSessionInfo newSessionInfo) {
517 assertNotNull(newSessionInfo);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900518 onSessionCreatedLatch.countDown();
519 }
520 });
521
522 mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1));
523 assertTrue(onSessionCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
524
525 List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
526 assertEquals(2, sessions.size());
527
528 // test setSessionVolume
529 RoutingSessionInfo sessionInfo = sessions.get(1);
530 int currentVolume = sessionInfo.getVolume();
531 int targetVolume = (currentVolume == 0) ? 1 : (currentVolume - 1);
532
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900533 MediaRouter2.ControllerCallback controllerCallback = new MediaRouter2.ControllerCallback() {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900534 @Override
535 public void onControllerUpdated(MediaRouter2.RoutingController controller) {
536 if (!TextUtils.equals(sessionInfo.getId(), controller.getId())) {
537 return;
538 }
539 if (controller.getVolume() == targetVolume) {
540 volumeChangedLatch.countDown();
541 }
542 }
543 };
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900544
545 addManagerCallback(new MediaRouter2Manager.Callback() {
546 @Override
Kyunglyul Hyunf064dcae2020-03-06 22:59:14 +0900547 public void onSessionUpdated(RoutingSessionInfo updatedSessionInfo) {
548 if (!TextUtils.equals(sessionInfo.getId(), updatedSessionInfo.getId())) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900549 return;
550 }
551
Kyunglyul Hyunf064dcae2020-03-06 22:59:14 +0900552 if (updatedSessionInfo.getVolume() == targetVolume) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900553 volumeChangedLatch.countDown();
554 }
555 }
556 });
557
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900558 try {
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900559 mRouter2.registerControllerCallback(mExecutor, controllerCallback);
560 mManager.setSessionVolume(sessionInfo, targetVolume);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900561 assertTrue(volumeChangedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
562 } finally {
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900563 mRouter2.unregisterControllerCallback(controllerCallback);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900564 }
565 }
566
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900567 /**
568 * Tests that {@link android.media.MediaRoute2ProviderService#notifyRequestFailed(long, int)}
569 * should invoke the callback only when the right requestId is used.
570 */
571 @Test
572 public void testOnRequestFailedCalledForProperRequestId() throws Exception {
573 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
574 MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
575
Hyundo Moon1c888e22020-03-15 19:46:41 +0900576 StubMediaRoute2ProviderService instance = StubMediaRoute2ProviderService.getInstance();
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900577 assertNotNull(instance);
578
579 final List<Long> requestIds = new ArrayList<>();
580 final CountDownLatch onSetRouteVolumeLatch = new CountDownLatch(1);
Hyundo Moon1c888e22020-03-15 19:46:41 +0900581 instance.setProxy(new StubMediaRoute2ProviderService.Proxy() {
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900582 @Override
583 public void onSetRouteVolume(String routeId, int volume, long requestId) {
584 requestIds.add(requestId);
585 onSetRouteVolumeLatch.countDown();
586 }
587 });
588
589 addManagerCallback(new MediaRouter2Manager.Callback() {});
590 mManager.setRouteVolume(volRoute, 0);
591 assertTrue(onSetRouteVolumeLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
592 assertFalse(requestIds.isEmpty());
593
594 final int failureReason = REASON_REJECTED;
595 final CountDownLatch onRequestFailedLatch = new CountDownLatch(1);
Hyundo Moon9b5e3922020-06-09 16:34:20 +0900596 final CountDownLatch onRequestFailedSecondCallLatch = new CountDownLatch(1);
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900597 addManagerCallback(new MediaRouter2Manager.Callback() {
598 @Override
599 public void onRequestFailed(int reason) {
600 if (reason == failureReason) {
Hyundo Moon9b5e3922020-06-09 16:34:20 +0900601 if (onRequestFailedLatch.getCount() > 0) {
602 onRequestFailedLatch.countDown();
603 } else {
604 onRequestFailedSecondCallLatch.countDown();
605 }
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900606 }
607 }
608 });
609
610 final long invalidRequestId = REQUEST_ID_NONE;
611 instance.notifyRequestFailed(invalidRequestId, failureReason);
612 assertFalse(onRequestFailedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
613
614 final long validRequestId = requestIds.get(0);
615 instance.notifyRequestFailed(validRequestId, failureReason);
616 assertTrue(onRequestFailedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Hyundo Moon9b5e3922020-06-09 16:34:20 +0900617
618 // Test calling notifyRequestFailed() multiple times with the same valid requestId.
619 // onRequestFailed() shouldn't be called since the requestId has been already handled.
620 instance.notifyRequestFailed(validRequestId, failureReason);
621 assertFalse(onRequestFailedSecondCallLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900622 }
623
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900624 @Test
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900625 public void testVolumeHandling() throws Exception {
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900626 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900627
628 MediaRoute2Info fixedVolumeRoute = routes.get(ROUTE_ID_FIXED_VOLUME);
629 MediaRoute2Info variableVolumeRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
Kyunglyul Hyun9b10a642019-10-08 15:29:23 +0900630
631 assertEquals(PLAYBACK_VOLUME_FIXED, fixedVolumeRoute.getVolumeHandling());
632 assertEquals(PLAYBACK_VOLUME_VARIABLE, variableVolumeRoute.getVolumeHandling());
633 assertEquals(VOLUME_MAX, variableVolumeRoute.getVolumeMax());
Kyunglyul Hyun9b10a642019-10-08 15:29:23 +0900634 }
635
Kyunglyul Hyunf0eb51b2020-04-14 19:56:16 +0900636 @Test
637 public void testRouter2SetOnGetControllerHintsListener() throws Exception {
638 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
639 addRouterCallback(new RouteCallback() {});
640
641 MediaRoute2Info route = routes.get(ROUTE_ID1);
642 assertNotNull(route);
643
644 final Bundle controllerHints = new Bundle();
645 controllerHints.putString(TEST_KEY, TEST_VALUE);
646 final CountDownLatch hintLatch = new CountDownLatch(1);
647 final MediaRouter2.OnGetControllerHintsListener listener =
648 route1 -> {
649 hintLatch.countDown();
650 return controllerHints;
651 };
652
653 final CountDownLatch successLatch = new CountDownLatch(1);
654 final CountDownLatch failureLatch = new CountDownLatch(1);
655
656 addManagerCallback(new MediaRouter2Manager.Callback() {
657 @Override
658 public void onTransferred(RoutingSessionInfo oldSession,
659 RoutingSessionInfo newSession) {
660 assertTrue(newSession.getSelectedRoutes().contains(route.getId()));
661 // The StubMediaRoute2ProviderService is supposed to set control hints
662 // with the given controllerHints.
663 Bundle controlHints = newSession.getControlHints();
664 assertNotNull(controlHints);
665 assertTrue(controlHints.containsKey(TEST_KEY));
666 assertEquals(TEST_VALUE, controlHints.getString(TEST_KEY));
667
668 successLatch.countDown();
669 }
670
671 @Override
672 public void onTransferFailed(RoutingSessionInfo session,
673 MediaRoute2Info requestedRoute) {
674 failureLatch.countDown();
675 }
676 });
677
678 mRouter2.setOnGetControllerHintsListener(listener);
679 mManager.selectRoute(mPackageName, route);
680 assertTrue(hintLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
681 assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
682
683 assertFalse(failureLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
684 }
685
Kyunglyul Hyun45512bb2020-05-08 15:21:13 +0900686 /**
687 * Tests if getSelectableRoutes and getDeselectableRoutes filter routes based on
688 * selected routes
689 */
690 @Test
691 public void testGetSelectableRoutes_notReturnsSelectedRoutes() throws Exception {
692 Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
693 addRouterCallback(new RouteCallback() {});
694
695 CountDownLatch onSessionCreatedLatch = new CountDownLatch(1);
696
697 addManagerCallback(new MediaRouter2Manager.Callback() {
698 @Override
699 public void onTransferred(RoutingSessionInfo oldSessionInfo,
700 RoutingSessionInfo newSessionInfo) {
701 assertNotNull(newSessionInfo);
702 List<String> selectedRoutes = mManager.getSelectedRoutes(newSessionInfo).stream()
703 .map(MediaRoute2Info::getId)
704 .collect(Collectors.toList());
705 for (MediaRoute2Info selectableRoute :
706 mManager.getSelectableRoutes(newSessionInfo)) {
707 assertFalse(selectedRoutes.contains(selectableRoute.getId()));
708 }
709 for (MediaRoute2Info deselectableRoute :
710 mManager.getDeselectableRoutes(newSessionInfo)) {
711 assertTrue(selectedRoutes.contains(deselectableRoute.getId()));
712 }
713 onSessionCreatedLatch.countDown();
714 }
715 });
716
717 mManager.selectRoute(mPackageName, routes.get(ROUTE_ID4_TO_SELECT_AND_DESELECT));
718 assertTrue(onSessionCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
719 }
720
Kyunglyul Hyunccb95872020-05-11 15:33:34 +0900721 @Test
722 public void testGetActiveSessions_returnsNonEmptyList() {
723 assertFalse(mManager.getActiveSessions().isEmpty());
724 }
725
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900726 Map<String, MediaRoute2Info> waitAndGetRoutesWithManager(List<String> routeFeatures)
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900727 throws Exception {
Kyunglyul Hyunc24317d2020-02-17 16:58:24 +0900728 CountDownLatch addedLatch = new CountDownLatch(1);
729 CountDownLatch featuresLatch = new CountDownLatch(1);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900730
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900731 // A dummy callback is required to send route feature info.
Hyundo Moon899535c2020-02-28 17:47:37 +0900732 RouteCallback routeCallback = new RouteCallback() {};
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900733 MediaRouter2Manager.Callback managerCallback = new MediaRouter2Manager.Callback() {
734 @Override
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900735 public void onRoutesAdded(List<MediaRoute2Info> routes) {
Kyunglyul Hyun350d7b42020-04-17 23:09:08 +0900736 for (MediaRoute2Info route : routes) {
737 if (!route.isSystemRoute()) {
Kyunglyul Hyunc24317d2020-02-17 16:58:24 +0900738 addedLatch.countDown();
Kyunglyul Hyun484074a2019-12-04 20:43:28 +0900739 break;
740 }
Kyunglyul Hyun7af73012019-10-11 20:01:30 +0900741 }
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900742 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900743
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900744 @Override
Kyunglyul Hyunf55befb2020-02-20 19:57:43 +0900745 public void onPreferredFeaturesChanged(String packageName,
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900746 List<String> preferredFeatures) {
Kyunglyul Hyune6b62382019-12-24 11:17:24 +0900747 if (TextUtils.equals(mPackageName, packageName)
Kyunglyul Hyunf55befb2020-02-20 19:57:43 +0900748 && preferredFeatures.size() == routeFeatures.size()
749 && preferredFeatures.containsAll(routeFeatures)) {
Kyunglyul Hyunc24317d2020-02-17 16:58:24 +0900750 featuresLatch.countDown();
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900751 }
752 }
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900753 };
754 mManager.registerCallback(mExecutor, managerCallback);
Kyunglyul Hyun91c792e2020-01-08 13:51:27 +0900755 mRouter2.registerRouteCallback(mExecutor, routeCallback,
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900756 new RouteDiscoveryPreference.Builder(routeFeatures, true).build());
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900757 try {
Kyunglyul Hyuna3be2de2020-06-02 17:42:36 +0900758 if (mManager.getAllRoutes().isEmpty()) {
759 addedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
760 }
761 featuresLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900762 return createRouteMap(mManager.getAvailableRoutes(mPackageName));
763 } finally {
Hyundo Moona64ca9e2019-12-27 17:41:17 +0900764 mRouter2.unregisterRouteCallback(routeCallback);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900765 mManager.unregisterCallback(managerCallback);
766 }
767 }
768
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900769 void awaitOnRouteChangedManager(Runnable task, String routeId,
770 Predicate<MediaRoute2Info> predicate) throws Exception {
771 CountDownLatch latch = new CountDownLatch(1);
772 MediaRouter2Manager.Callback callback = new MediaRouter2Manager.Callback() {
773 @Override
774 public void onRoutesChanged(List<MediaRoute2Info> changed) {
775 MediaRoute2Info route = createRouteMap(changed).get(routeId);
776 if (route != null && predicate.test(route)) {
777 latch.countDown();
778 }
779 }
780 };
781 mManager.registerCallback(mExecutor, callback);
782 try {
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900783 task.run();
Kyunglyul Hyun4ed68752019-11-04 16:05:34 +0900784 assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
785 } finally {
786 mManager.unregisterCallback(callback);
787 }
Kyunglyul Hyun7af73012019-10-11 20:01:30 +0900788 }
789
Kyunglyul Hyun23b3aaa2019-08-06 11:17:16 +0900790 // Helper for getting routes easily
791 static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900792 Map<String, MediaRoute2Info> routeMap = new HashMap<>();
793 for (MediaRoute2Info route : routes) {
Hyundo Moon5de706f2020-02-03 20:16:33 +0900794 routeMap.put(route.getOriginalId(), route);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900795 }
796 return routeMap;
797 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900798
799 private void addManagerCallback(MediaRouter2Manager.Callback callback) {
800 mManagerCallbacks.add(callback);
801 mManager.registerCallback(mExecutor, callback);
802 }
803
Hyundo Moon63a05402019-12-19 20:13:56 +0900804 private void addRouterCallback(RouteCallback routeCallback) {
805 mRouteCallbacks.add(routeCallback);
Kyunglyul Hyun616096e2020-01-09 16:15:03 +0900806 mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900807 }
808
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900809 private void addTransferCallback(TransferCallback transferCallback) {
810 mTransferCallbacks.add(transferCallback);
811 mRouter2.registerTransferCallback(mExecutor, transferCallback);
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900812 }
813
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900814 private void clearCallbacks() {
815 for (MediaRouter2Manager.Callback callback : mManagerCallbacks) {
816 mManager.unregisterCallback(callback);
817 }
818 mManagerCallbacks.clear();
819
Hyundo Moon63a05402019-12-19 20:13:56 +0900820 for (RouteCallback routeCallback : mRouteCallbacks) {
Hyundo Moona64ca9e2019-12-27 17:41:17 +0900821 mRouter2.unregisterRouteCallback(routeCallback);
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900822 }
Hyundo Moon63a05402019-12-19 20:13:56 +0900823 mRouteCallbacks.clear();
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900824
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900825 for (MediaRouter2.TransferCallback transferCallback : mTransferCallbacks) {
826 mRouter2.unregisterTransferCallback(transferCallback);
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900827 }
Kyunglyul Hyun3729e9f2020-02-12 10:50:43 +0900828 mTransferCallbacks.clear();
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900829 }
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000830
831 private void releaseAllSessions() {
832 // ensure ManagerRecord in MediaRouter2ServiceImpl
833 addManagerCallback(new MediaRouter2Manager.Callback());
834
835 for (RoutingSessionInfo session : mManager.getActiveSessions()) {
Kyunglyul Hyuna3365d72020-02-20 13:46:45 +0900836 mManager.releaseSession(session);
Kyunglyul Hyunc6583832020-01-17 11:11:46 +0000837 }
838 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000839}