1 /*
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 
17 package com.android.settingslib.media;
18 
19 import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
20 import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
21 import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
22 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
23 import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
24 import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
25 import static android.media.MediaRoute2ProviderService.REASON_NETWORK_ERROR;
26 import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
27 
28 import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_SELECTED;
29 
30 import static com.google.common.truth.Truth.assertThat;
31 
32 import static org.mockito.ArgumentMatchers.any;
33 import static org.mockito.Mockito.doReturn;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.never;
36 import static org.mockito.Mockito.spy;
37 import static org.mockito.Mockito.verify;
38 import static org.mockito.Mockito.when;
39 
40 import android.bluetooth.BluetoothDevice;
41 import android.content.ComponentName;
42 import android.content.Context;
43 import android.media.MediaRoute2Info;
44 import android.media.MediaRouter2Manager;
45 import android.media.RouteListingPreference;
46 import android.media.RoutingSessionInfo;
47 import android.media.session.MediaSessionManager;
48 import android.os.Build;
49 
50 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
51 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
52 import com.android.settingslib.bluetooth.LocalBluetoothManager;
53 import com.android.settingslib.testutils.shadow.ShadowRouter2Manager;
54 
55 import com.google.common.collect.ImmutableList;
56 
57 import org.junit.Before;
58 import org.junit.Test;
59 import org.junit.runner.RunWith;
60 import org.mockito.Mock;
61 import org.mockito.MockitoAnnotations;
62 import org.robolectric.RobolectricTestRunner;
63 import org.robolectric.RuntimeEnvironment;
64 import org.robolectric.annotation.Config;
65 import org.robolectric.util.ReflectionHelpers;
66 
67 import java.util.ArrayList;
68 import java.util.List;
69 import java.util.Set;
70 
71 @RunWith(RobolectricTestRunner.class)
72 @Config(shadows = {ShadowRouter2Manager.class})
73 public class InfoMediaManagerTest {
74 
75     private static final String TEST_PACKAGE_NAME = "com.test.packagename";
76     private static final String TEST_PACKAGE_NAME_2 = "com.test.packagename2";
77     private static final String TEST_ID = "test_id";
78     private static final String TEST_ID_1 = "test_id_1";
79     private static final String TEST_ID_2 = "test_id_2";
80     private static final String TEST_ID_3 = "test_id_3";
81     private static final String TEST_ID_4 = "test_id_4";
82 
83     private static final String TEST_NAME = "test_name";
84     private static final String TEST_DUPLICATED_ID_1 = "test_duplicated_id_1";
85     private static final String TEST_DUPLICATED_ID_2 = "test_duplicated_id_2";
86     private static final String TEST_DUPLICATED_ID_3 = "test_duplicated_id_3";
87 
88     @Mock
89     private MediaRouter2Manager mRouterManager;
90     @Mock
91     private LocalBluetoothManager mLocalBluetoothManager;
92     @Mock
93     private MediaManager.MediaDeviceCallback mCallback;
94     @Mock
95     private MediaSessionManager mMediaSessionManager;
96     @Mock
97     private ComponentName mComponentName;
98 
99     private InfoMediaManager mInfoMediaManager;
100     private Context mContext;
101     private ShadowRouter2Manager mShadowRouter2Manager;
102 
103     @Before
setUp()104     public void setUp() {
105         MockitoAnnotations.initMocks(this);
106         mContext = spy(RuntimeEnvironment.application);
107 
108         doReturn(mMediaSessionManager).when(mContext).getSystemService(
109                 Context.MEDIA_SESSION_SERVICE);
110         mInfoMediaManager =
111                 new InfoMediaManager(mContext, TEST_PACKAGE_NAME, null, mLocalBluetoothManager);
112         mShadowRouter2Manager = ShadowRouter2Manager.getShadow();
113         mInfoMediaManager.mRouterManager = MediaRouter2Manager.getInstance(mContext);
114     }
115 
116     @Test
stopScan_notStartFirst_notCallsUnregister()117     public void stopScan_notStartFirst_notCallsUnregister() {
118         mInfoMediaManager.mRouterManager = mRouterManager;
119         mInfoMediaManager.stopScan();
120 
121         verify(mRouterManager, never()).unregisterScanRequest();
122     }
123 
124     @Test
stopScan_startFirst_callsUnregister()125     public void stopScan_startFirst_callsUnregister() {
126         mInfoMediaManager.mRouterManager = mRouterManager;
127         mInfoMediaManager.startScan();
128         mInfoMediaManager.stopScan();
129 
130         verify(mRouterManager).unregisterScanRequest();
131     }
132 
133     @Test
onRouteAdded_getAvailableRoutes_shouldAddMediaDevice()134     public void onRouteAdded_getAvailableRoutes_shouldAddMediaDevice() {
135         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
136         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
137         routingSessionInfos.add(sessionInfo);
138         final List<String> selectedRoutes = new ArrayList<>();
139         selectedRoutes.add(TEST_ID);
140         when(sessionInfo.getSelectedRoutes()).thenReturn(selectedRoutes);
141         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
142 
143         final MediaRoute2Info info = mock(MediaRoute2Info.class);
144         when(info.getId()).thenReturn(TEST_ID);
145         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
146         when(info.getDeduplicationIds()).thenReturn(Set.of());
147 
148         final List<MediaRoute2Info> routes = new ArrayList<>();
149         routes.add(info);
150         mShadowRouter2Manager.setTransferableRoutes(routes);
151 
152         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
153         assertThat(mediaDevice).isNull();
154 
155         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
156 
157         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
158         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
159         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
160         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
161     }
162 
163     @Test
onSessionReleased_shouldUpdateConnectedDevice()164     public void onSessionReleased_shouldUpdateConnectedDevice() {
165         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
166         final RoutingSessionInfo sessionInfo1 = mock(RoutingSessionInfo.class);
167         routingSessionInfos.add(sessionInfo1);
168         final RoutingSessionInfo sessionInfo2 = mock(RoutingSessionInfo.class);
169         routingSessionInfos.add(sessionInfo2);
170 
171         final List<String> selectedRoutesSession1 = new ArrayList<>();
172         selectedRoutesSession1.add(TEST_ID_1);
173         when(sessionInfo1.getSelectedRoutes()).thenReturn(selectedRoutesSession1);
174 
175         final List<String> selectedRoutesSession2 = new ArrayList<>();
176         selectedRoutesSession2.add(TEST_ID_2);
177         when(sessionInfo2.getSelectedRoutes()).thenReturn(selectedRoutesSession2);
178 
179         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
180 
181         final MediaRoute2Info info1 = mock(MediaRoute2Info.class);
182         when(info1.getId()).thenReturn(TEST_ID_1);
183         when(info1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
184 
185         final MediaRoute2Info info2 = mock(MediaRoute2Info.class);
186         when(info2.getId()).thenReturn(TEST_ID_2);
187         when(info2.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
188 
189         final List<MediaRoute2Info> routes = new ArrayList<>();
190         routes.add(info1);
191         routes.add(info2);
192         mShadowRouter2Manager.setAllRoutes(routes);
193         mShadowRouter2Manager.setTransferableRoutes(routes);
194 
195         final MediaDevice mediaDevice1 = mInfoMediaManager.findMediaDevice(TEST_ID_1);
196         assertThat(mediaDevice1).isNull();
197         final MediaDevice mediaDevice2 = mInfoMediaManager.findMediaDevice(TEST_ID_2);
198         assertThat(mediaDevice2).isNull();
199 
200         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
201         final MediaDevice infoDevice1 = mInfoMediaManager.mMediaDevices.get(0);
202         assertThat(infoDevice1.getId()).isEqualTo(TEST_ID_1);
203         final MediaDevice infoDevice2 = mInfoMediaManager.mMediaDevices.get(1);
204         assertThat(infoDevice2.getId()).isEqualTo(TEST_ID_2);
205         // The active routing session is the last one in the list, which maps to infoDevice2.
206         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice2);
207 
208         routingSessionInfos.remove(sessionInfo2);
209         mInfoMediaManager.mMediaRouterCallback.onSessionReleased(sessionInfo2);
210         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice1);
211     }
212 
213     @Test
onRouteAdded_buildAllRoutes_shouldAddMediaDevice()214     public void onRouteAdded_buildAllRoutes_shouldAddMediaDevice() {
215         final MediaRoute2Info info = mock(MediaRoute2Info.class);
216         when(info.getId()).thenReturn(TEST_ID);
217         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
218         when(info.isSystemRoute()).thenReturn(true);
219 
220         final List<MediaRoute2Info> routes = new ArrayList<>();
221         routes.add(info);
222         mShadowRouter2Manager.setAllRoutes(routes);
223 
224         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
225         assertThat(mediaDevice).isNull();
226 
227         mInfoMediaManager.mPackageName = "";
228         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
229 
230         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
231         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
232         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
233     }
234 
235     @Test
onPreferredFeaturesChanged_samePackageName_shouldAddMediaDevice()236     public void onPreferredFeaturesChanged_samePackageName_shouldAddMediaDevice() {
237         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
238         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
239         routingSessionInfos.add(sessionInfo);
240         final List<String> selectedRoutes = new ArrayList<>();
241         selectedRoutes.add(TEST_ID);
242         when(sessionInfo.getSelectedRoutes()).thenReturn(selectedRoutes);
243         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
244 
245         final MediaRoute2Info info = mock(MediaRoute2Info.class);
246         when(info.getId()).thenReturn(TEST_ID);
247         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
248         when(info.getDeduplicationIds()).thenReturn(Set.of());
249 
250         final List<MediaRoute2Info> routes = new ArrayList<>();
251         routes.add(info);
252         mShadowRouter2Manager.setTransferableRoutes(routes);
253 
254         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
255         assertThat(mediaDevice).isNull();
256 
257         mInfoMediaManager.mMediaRouterCallback.onPreferredFeaturesChanged(TEST_PACKAGE_NAME, null);
258 
259         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
260         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
261         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
262         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
263     }
264 
265     @Test
onPreferredFeaturesChanged_differentPackageName_doNothing()266     public void onPreferredFeaturesChanged_differentPackageName_doNothing() {
267         mInfoMediaManager.mMediaRouterCallback.onPreferredFeaturesChanged("com.fake.play", null);
268 
269         assertThat(mInfoMediaManager.mMediaDevices).hasSize(0);
270     }
271 
272     @Test
onRoutesChanged_getAvailableRoutes_shouldAddMediaDevice()273     public void onRoutesChanged_getAvailableRoutes_shouldAddMediaDevice() {
274         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
275         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
276         routingSessionInfos.add(sessionInfo);
277         final List<String> selectedRoutes = new ArrayList<>();
278         selectedRoutes.add(TEST_ID);
279         when(sessionInfo.getSelectedRoutes()).thenReturn(selectedRoutes);
280         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
281 
282         final MediaRoute2Info info = mock(MediaRoute2Info.class);
283         when(info.getId()).thenReturn(TEST_ID);
284         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
285         when(info.getDeduplicationIds()).thenReturn(Set.of());
286 
287         final List<MediaRoute2Info> routes = new ArrayList<>();
288         routes.add(info);
289         mShadowRouter2Manager.setTransferableRoutes(routes);
290 
291         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
292         assertThat(mediaDevice).isNull();
293 
294         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
295 
296         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
297         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
298         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
299         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
300     }
301 
302     @Test
onRoutesChanged_getAvailableRoutes_shouldFilterDevice()303     public void onRoutesChanged_getAvailableRoutes_shouldFilterDevice() {
304         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
305                 Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
306         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
307         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
308         routingSessionInfos.add(sessionInfo);
309 
310         final List<String> selectedRoutes = new ArrayList<>();
311         selectedRoutes.add(TEST_ID);
312         when(sessionInfo.getSelectedRoutes()).thenReturn(selectedRoutes);
313         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
314 
315         mShadowRouter2Manager.setTransferableRoutes(getRoutesListWithDuplicatedIds());
316 
317         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
318         assertThat(mediaDevice).isNull();
319 
320         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
321 
322         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
323         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
324         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
325         assertThat(mInfoMediaManager.mMediaDevices).hasSize(2);
326     }
327 
328     @Test
onRouteChanged_getAvailableRoutesWithPreferenceListExit_ordersRoutes()329     public void onRouteChanged_getAvailableRoutesWithPreferenceListExit_ordersRoutes() {
330         RouteListingPreference routeListingPreference = setUpPreferenceList(TEST_PACKAGE_NAME);
331         setUpSelectedRoutes(TEST_PACKAGE_NAME);
332 
333         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
334         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
335         routingSessionInfos.add(sessionInfo);
336 
337         when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME)).thenReturn(routingSessionInfos);
338         when(sessionInfo.getSelectedRoutes()).thenReturn(ImmutableList.of(TEST_ID));
339 
340         setAvailableRoutesList(TEST_PACKAGE_NAME);
341 
342         mInfoMediaManager.mRouterManager = mRouterManager;
343         mInfoMediaManager.mMediaRouterCallback.onRouteListingPreferenceUpdated(TEST_PACKAGE_NAME,
344                 routeListingPreference);
345         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
346 
347         assertThat(mInfoMediaManager.mMediaDevices).hasSize(4);
348         assertThat(mInfoMediaManager.mMediaDevices.get(0).getId()).isEqualTo(TEST_ID);
349         assertThat(mInfoMediaManager.mMediaDevices.get(1).getId()).isEqualTo(TEST_ID_1);
350         assertThat(mInfoMediaManager.mMediaDevices.get(2).getId()).isEqualTo(TEST_ID_4);
351         assertThat(mInfoMediaManager.mMediaDevices.get(2).isSuggestedDevice()).isTrue();
352         assertThat(mInfoMediaManager.mMediaDevices.get(3).getId()).isEqualTo(TEST_ID_3);
353     }
354 
355     @Test
onRouteChanged_preferenceListUpdateWithDifferentPkg_notOrdersRoutes()356     public void onRouteChanged_preferenceListUpdateWithDifferentPkg_notOrdersRoutes() {
357         RouteListingPreference routeListingPreference = setUpPreferenceList(TEST_PACKAGE_NAME_2);
358         setUpSelectedRoutes(TEST_PACKAGE_NAME);
359 
360         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
361         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
362         routingSessionInfos.add(sessionInfo);
363 
364         when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME)).thenReturn(routingSessionInfos);
365         when(sessionInfo.getSelectedRoutes()).thenReturn(ImmutableList.of(TEST_ID));
366 
367         setAvailableRoutesList(TEST_PACKAGE_NAME);
368         mInfoMediaManager.mRouterManager = mRouterManager;
369         mInfoMediaManager.mMediaRouterCallback.onRouteListingPreferenceUpdated(TEST_PACKAGE_NAME_2,
370                 routeListingPreference);
371         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
372 
373         assertThat(mInfoMediaManager.mMediaDevices).hasSize(1);
374         assertThat(mInfoMediaManager.mMediaDevices.get(0).getId()).isEqualTo(TEST_ID);
375     }
376 
setUpPreferenceList(String packageName)377     private RouteListingPreference setUpPreferenceList(String packageName) {
378         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
379                 Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
380         final List<RouteListingPreference.Item> preferenceItemList = new ArrayList<>();
381         RouteListingPreference.Item item1 =
382                 new RouteListingPreference.Item.Builder(TEST_ID_4)
383                         .setFlags(RouteListingPreference.Item.FLAG_SUGGESTED)
384                         .build();
385         RouteListingPreference.Item item2 = new RouteListingPreference.Item.Builder(
386                 TEST_ID_3).build();
387         preferenceItemList.add(item1);
388         preferenceItemList.add(item2);
389 
390         RouteListingPreference routeListingPreference =
391                 new RouteListingPreference.Builder().setItems(
392                         preferenceItemList).setUseSystemOrdering(false).build();
393         when(mRouterManager.getRouteListingPreference(packageName))
394                 .thenReturn(routeListingPreference);
395         return routeListingPreference;
396     }
397 
setUpSelectedRoutes(String packageName)398     private void setUpSelectedRoutes(String packageName) {
399         final List<MediaRoute2Info> selectedRoutes = new ArrayList<>();
400         final MediaRoute2Info info = mock(MediaRoute2Info.class);
401         when(info.getId()).thenReturn(TEST_ID);
402         when(info.getClientPackageName()).thenReturn(packageName);
403         when(info.isSystemRoute()).thenReturn(true);
404         selectedRoutes.add(info);
405         when(mRouterManager.getSelectedRoutes(any())).thenReturn(selectedRoutes);
406     }
407 
setAvailableRoutesList(String packageName)408     private List<MediaRoute2Info> setAvailableRoutesList(String packageName) {
409         final List<MediaRoute2Info> availableRoutes = new ArrayList<>();
410         final MediaRoute2Info availableInfo1 = mock(MediaRoute2Info.class);
411         when(availableInfo1.getId()).thenReturn(TEST_ID_2);
412         when(availableInfo1.getClientPackageName()).thenReturn(packageName);
413         when(availableInfo1.getType()).thenReturn(TYPE_REMOTE_TV);
414         availableRoutes.add(availableInfo1);
415 
416         final MediaRoute2Info availableInfo2 = mock(MediaRoute2Info.class);
417         when(availableInfo2.getId()).thenReturn(TEST_ID_3);
418         when(availableInfo2.getClientPackageName()).thenReturn(packageName);
419         availableRoutes.add(availableInfo2);
420 
421         final MediaRoute2Info availableInfo3 = mock(MediaRoute2Info.class);
422         when(availableInfo3.getId()).thenReturn(TEST_ID_4);
423         when(availableInfo3.getClientPackageName()).thenReturn(packageName);
424         availableRoutes.add(availableInfo3);
425 
426         final MediaRoute2Info availableInfo4 = mock(MediaRoute2Info.class);
427         when(availableInfo4.getId()).thenReturn(TEST_ID_1);
428         when(availableInfo4.isSystemRoute()).thenReturn(true);
429         when(availableInfo4.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
430         availableRoutes.add(availableInfo4);
431 
432         when(mRouterManager.getAvailableRoutes(packageName)).thenReturn(availableRoutes);
433 
434         return availableRoutes;
435     }
436 
437     @Test
onRoutesChanged_buildAllRoutes_shouldAddMediaDevice()438     public void onRoutesChanged_buildAllRoutes_shouldAddMediaDevice() {
439         final MediaRoute2Info info = mock(MediaRoute2Info.class);
440         when(info.getId()).thenReturn(TEST_ID);
441         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
442         when(info.isSystemRoute()).thenReturn(true);
443         when(info.getDeduplicationIds()).thenReturn(Set.of());
444 
445         final List<MediaRoute2Info> routes = new ArrayList<>();
446         routes.add(info);
447         mShadowRouter2Manager.setAllRoutes(routes);
448 
449         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
450         assertThat(mediaDevice).isNull();
451 
452         mInfoMediaManager.mPackageName = "";
453         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
454 
455         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
456         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
457         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
458     }
459 
460     @Test
hasPreferenceRouteListing_oldSdkVersion_returnsFalse()461     public void hasPreferenceRouteListing_oldSdkVersion_returnsFalse() {
462         assertThat(mInfoMediaManager.preferRouteListingOrdering()).isFalse();
463     }
464 
465     @Test
hasPreferenceRouteListing_newSdkVersionWithPreferenceExist_returnsTrue()466     public void hasPreferenceRouteListing_newSdkVersionWithPreferenceExist_returnsTrue() {
467         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
468                 Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
469         when(mRouterManager.getRouteListingPreference(any())).thenReturn(
470                 new RouteListingPreference.Builder().setItems(
471                         ImmutableList.of()).setUseSystemOrdering(false).build());
472         mInfoMediaManager.mRouterManager = mRouterManager;
473 
474         assertThat(mInfoMediaManager.preferRouteListingOrdering()).isTrue();
475     }
476 
477     @Test
hasPreferenceRouteListing_newSdkVersionWithPreferenceNotExist_returnsFalse()478     public void hasPreferenceRouteListing_newSdkVersionWithPreferenceNotExist_returnsFalse() {
479         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
480                 Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
481 
482         when(mRouterManager.getRouteListingPreference(any())).thenReturn(null);
483 
484         assertThat(mInfoMediaManager.preferRouteListingOrdering()).isFalse();
485     }
486 
487     @Test
getInAppOnlyItemRoutingReceiver_oldSdkVersion_returnsNull()488     public void getInAppOnlyItemRoutingReceiver_oldSdkVersion_returnsNull() {
489         assertThat(mInfoMediaManager.getLinkedItemComponentName()).isNull();
490     }
491 
492     @Test
getInAppOnlyItemRoutingReceiver_newSdkVersionWithReceiverExist_returns()493     public void getInAppOnlyItemRoutingReceiver_newSdkVersionWithReceiverExist_returns() {
494         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
495                 Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
496         when(mRouterManager.getRouteListingPreference(any())).thenReturn(
497                 new RouteListingPreference.Builder().setItems(
498                         ImmutableList.of()).setUseSystemOrdering(
499                         false).setLinkedItemComponentName(mComponentName).build());
500         mInfoMediaManager.mRouterManager = mRouterManager;
501 
502         assertThat(mInfoMediaManager.getLinkedItemComponentName()).isEqualTo(mComponentName);
503     }
504 
getRoutesListWithDuplicatedIds()505     private List<MediaRoute2Info> getRoutesListWithDuplicatedIds() {
506         final List<MediaRoute2Info> routes = new ArrayList<>();
507         final MediaRoute2Info info = mock(MediaRoute2Info.class);
508         when(info.getId()).thenReturn(TEST_ID);
509         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
510         when(info.isSystemRoute()).thenReturn(true);
511         when(info.getDeduplicationIds()).thenReturn(
512                 Set.of(TEST_DUPLICATED_ID_1, TEST_DUPLICATED_ID_2));
513         routes.add(info);
514 
515         final MediaRoute2Info info1 = mock(MediaRoute2Info.class);
516         when(info1.getId()).thenReturn(TEST_ID_1);
517         when(info1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
518         when(info1.isSystemRoute()).thenReturn(true);
519         when(info1.getDeduplicationIds()).thenReturn(Set.of(TEST_DUPLICATED_ID_3));
520         routes.add(info1);
521 
522         final MediaRoute2Info info2 = mock(MediaRoute2Info.class);
523         when(info2.getId()).thenReturn(TEST_ID_2);
524         when(info2.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
525         when(info2.isSystemRoute()).thenReturn(true);
526         when(info2.getDeduplicationIds()).thenReturn(Set.of(TEST_DUPLICATED_ID_3));
527         routes.add(info2);
528 
529         final MediaRoute2Info info3 = mock(MediaRoute2Info.class);
530         when(info3.getId()).thenReturn(TEST_ID_3);
531         when(info3.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
532         when(info3.isSystemRoute()).thenReturn(true);
533         when(info3.getDeduplicationIds()).thenReturn(Set.of(TEST_DUPLICATED_ID_1));
534         routes.add(info3);
535 
536         final MediaRoute2Info info4 = mock(MediaRoute2Info.class);
537         when(info4.getId()).thenReturn(TEST_ID_4);
538         when(info4.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
539         when(info4.isSystemRoute()).thenReturn(true);
540         when(info4.getDeduplicationIds()).thenReturn(Set.of(TEST_DUPLICATED_ID_2));
541         routes.add(info4);
542 
543         return routes;
544     }
545 
546     @Test
connectDeviceWithoutPackageName_noSession_returnFalse()547     public void connectDeviceWithoutPackageName_noSession_returnFalse() {
548         final MediaRoute2Info info = mock(MediaRoute2Info.class);
549         final MediaDevice device = new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager,
550                 info, TEST_PACKAGE_NAME);
551 
552         final List<RoutingSessionInfo> infos = new ArrayList<>();
553 
554         mShadowRouter2Manager.setRemoteSessions(infos);
555 
556         assertThat(mInfoMediaManager.connectDeviceWithoutPackageName(device)).isFalse();
557     }
558 
559     @Test
onRoutesRemoved_getAvailableRoutes_shouldAddMediaDevice()560     public void onRoutesRemoved_getAvailableRoutes_shouldAddMediaDevice() {
561         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
562         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
563         routingSessionInfos.add(sessionInfo);
564         final List<String> selectedRoutes = new ArrayList<>();
565         selectedRoutes.add(TEST_ID);
566         when(sessionInfo.getSelectedRoutes()).thenReturn(selectedRoutes);
567         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
568 
569         final MediaRoute2Info info = mock(MediaRoute2Info.class);
570         when(info.getId()).thenReturn(TEST_ID);
571         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
572         when(info.getDeduplicationIds()).thenReturn(Set.of());
573 
574         final List<MediaRoute2Info> routes = new ArrayList<>();
575         routes.add(info);
576         mShadowRouter2Manager.setTransferableRoutes(routes);
577 
578         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
579         assertThat(mediaDevice).isNull();
580 
581         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
582 
583         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
584         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
585         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
586         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
587     }
588 
589     @Test
onRoutesRemoved_buildAllRoutes_shouldAddMediaDevice()590     public void onRoutesRemoved_buildAllRoutes_shouldAddMediaDevice() {
591         final MediaRoute2Info info = mock(MediaRoute2Info.class);
592         when(info.getId()).thenReturn(TEST_ID);
593         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
594         when(info.isSystemRoute()).thenReturn(true);
595 
596         final List<MediaRoute2Info> routes = new ArrayList<>();
597         routes.add(info);
598         when(mRouterManager.getAllRoutes()).thenReturn(routes);
599 
600         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
601         assertThat(mediaDevice).isNull();
602 
603         mInfoMediaManager.mPackageName = "";
604         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
605 
606         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
607         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
608         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
609     }
610 
611     @Test
addDeviceToPlayMedia_packageNameIsNull_returnFalse()612     public void addDeviceToPlayMedia_packageNameIsNull_returnFalse() {
613         mInfoMediaManager.mPackageName = null;
614         final MediaDevice device = mock(MediaDevice.class);
615 
616         assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isFalse();
617     }
618 
619     @Test
addDeviceToPlayMedia_containSelectableRoutes_returnTrue()620     public void addDeviceToPlayMedia_containSelectableRoutes_returnTrue() {
621         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
622         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
623         routingSessionInfos.add(info);
624 
625         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
626         final MediaDevice device =
627                 new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
628                         TEST_PACKAGE_NAME);
629 
630         final List<String> list = new ArrayList<>();
631         list.add(TEST_ID);
632 
633         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
634         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
635         when(info.getSelectableRoutes()).thenReturn(list);
636         when(route2Info.getId()).thenReturn(TEST_ID);
637         when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
638 
639         assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isTrue();
640     }
641 
642     @Test
addDeviceToPlayMedia_notContainSelectableRoutes_returnFalse()643     public void addDeviceToPlayMedia_notContainSelectableRoutes_returnFalse() {
644         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
645         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
646         routingSessionInfos.add(info);
647 
648         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
649         final MediaDevice device =
650                 new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
651                         TEST_PACKAGE_NAME);
652 
653         final List<String> list = new ArrayList<>();
654         list.add("fake_id");
655 
656         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
657         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
658         when(info.getSelectableRoutes()).thenReturn(list);
659         when(route2Info.getId()).thenReturn(TEST_ID);
660         when(route2Info.getName()).thenReturn(TEST_NAME);
661         when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
662 
663         assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isFalse();
664     }
665 
666     @Test
removeDeviceFromMedia_packageNameIsNull_returnFalse()667     public void removeDeviceFromMedia_packageNameIsNull_returnFalse() {
668         mInfoMediaManager.mPackageName = null;
669         final MediaDevice device = mock(MediaDevice.class);
670 
671         assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isFalse();
672     }
673 
674     @Test
removeDeviceFromMedia_containSelectedRoutes_returnTrue()675     public void removeDeviceFromMedia_containSelectedRoutes_returnTrue() {
676         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
677         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
678         routingSessionInfos.add(info);
679 
680         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
681         final MediaDevice device =
682                 new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
683                         TEST_PACKAGE_NAME);
684 
685         final List<String> list = new ArrayList<>();
686         list.add(TEST_ID);
687 
688         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
689         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
690         when(info.getSelectedRoutes()).thenReturn(list);
691         when(route2Info.getId()).thenReturn(TEST_ID);
692         when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
693 
694         assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isTrue();
695     }
696 
697     @Test
removeDeviceFromMedia_notContainSelectedRoutes_returnFalse()698     public void removeDeviceFromMedia_notContainSelectedRoutes_returnFalse() {
699         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
700         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
701         routingSessionInfos.add(info);
702 
703         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
704         final MediaDevice device =
705                 new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
706                         TEST_PACKAGE_NAME);
707 
708         final List<String> list = new ArrayList<>();
709         list.add("fake_id");
710 
711         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
712         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
713         when(info.getSelectedRoutes()).thenReturn(list);
714         when(route2Info.getId()).thenReturn(TEST_ID);
715         when(route2Info.getName()).thenReturn(TEST_NAME);
716         when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
717 
718         assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isFalse();
719     }
720 
721     @Test
getSelectableMediaDevice_packageNameIsNull_returnFalse()722     public void getSelectableMediaDevice_packageNameIsNull_returnFalse() {
723         mInfoMediaManager.mPackageName = null;
724 
725         assertThat(mInfoMediaManager.getSelectableMediaDevice()).isEmpty();
726     }
727 
728     @Test
getSelectableMediaDevice_notContainPackageName_returnEmpty()729     public void getSelectableMediaDevice_notContainPackageName_returnEmpty() {
730         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
731         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
732         routingSessionInfos.add(info);
733 
734         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
735         when(info.getClientPackageName()).thenReturn("com.fake.packagename");
736 
737         assertThat(mInfoMediaManager.getSelectableMediaDevice()).isEmpty();
738     }
739 
740     @Test
getDeselectableMediaDevice_packageNameIsNull_returnFalse()741     public void getDeselectableMediaDevice_packageNameIsNull_returnFalse() {
742         mInfoMediaManager.mPackageName = null;
743 
744         assertThat(mInfoMediaManager.getDeselectableMediaDevice()).isEmpty();
745     }
746 
747     @Test
getDeselectableMediaDevice_checkList()748     public void getDeselectableMediaDevice_checkList() {
749         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
750         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
751         routingSessionInfos.add(info);
752         final List<MediaRoute2Info> mediaRoute2Infos = new ArrayList<>();
753         final MediaRoute2Info mediaRoute2Info = mock(MediaRoute2Info.class);
754         mediaRoute2Infos.add(mediaRoute2Info);
755         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
756         mShadowRouter2Manager.setDeselectableRoutes(mediaRoute2Infos);
757         when(mediaRoute2Info.getName()).thenReturn(TEST_NAME);
758         when(mediaRoute2Info.getId()).thenReturn(TEST_ID);
759 
760         final List<MediaDevice> mediaDevices = mInfoMediaManager.getDeselectableMediaDevice();
761 
762         assertThat(mediaDevices.size()).isEqualTo(1);
763         assertThat(mediaDevices.get(0).getName()).isEqualTo(TEST_NAME);
764     }
765 
766     @Test
adjustSessionVolume_routingSessionInfoIsNull_noCrash()767     public void adjustSessionVolume_routingSessionInfoIsNull_noCrash() {
768         mInfoMediaManager.adjustSessionVolume(null, 10);
769     }
770 
771     @Test
adjustSessionVolume_packageNameIsNull_noCrash()772     public void adjustSessionVolume_packageNameIsNull_noCrash() {
773         mInfoMediaManager.mPackageName = null;
774 
775         mInfoMediaManager.adjustSessionVolume(10);
776     }
777 
778     @Test
getSessionVolumeMax_packageNameIsNull_returnNotFound()779     public void getSessionVolumeMax_packageNameIsNull_returnNotFound() {
780         mInfoMediaManager.mPackageName = null;
781 
782         assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1);
783     }
784 
785     @Test
getSessionVolumeMax_containPackageName_returnMaxVolume()786     public void getSessionVolumeMax_containPackageName_returnMaxVolume() {
787         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
788         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
789         routingSessionInfos.add(info);
790 
791         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
792         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
793 
794         mInfoMediaManager.getSessionVolumeMax();
795 
796         verify(info).getVolumeMax();
797     }
798 
799     @Test
getSessionVolumeMax_routeSessionInfoIsNull_returnNotFound()800     public void getSessionVolumeMax_routeSessionInfoIsNull_returnNotFound() {
801         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
802         final RoutingSessionInfo info = null;
803         routingSessionInfos.add(info);
804 
805         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
806 
807         assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1);
808     }
809 
810     @Test
getSessionVolume_packageNameIsNull_returnNotFound()811     public void getSessionVolume_packageNameIsNull_returnNotFound() {
812         mInfoMediaManager.mPackageName = null;
813 
814         assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1);
815     }
816 
817     @Test
getSessionVolume_containPackageName_returnMaxVolume()818     public void getSessionVolume_containPackageName_returnMaxVolume() {
819         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
820         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
821         routingSessionInfos.add(info);
822 
823         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
824         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
825 
826         mInfoMediaManager.getSessionVolume();
827 
828         verify(info).getVolume();
829     }
830 
831     @Test
getSessionVolume_routeSessionInfoIsNull_returnNotFound()832     public void getSessionVolume_routeSessionInfoIsNull_returnNotFound() {
833         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
834         final RoutingSessionInfo info = null;
835         routingSessionInfos.add(info);
836 
837         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
838 
839         assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1);
840     }
841 
842     @Test
getActiveMediaSession_returnActiveSession()843     public void getActiveMediaSession_returnActiveSession() {
844         RoutingSessionInfo sysSessionInfo = mock(RoutingSessionInfo.class);
845         final List<RoutingSessionInfo> infos = new ArrayList<>();
846         infos.add(mock(RoutingSessionInfo.class));
847         final List<RoutingSessionInfo> activeSessionInfos = new ArrayList<>();
848         activeSessionInfos.add(sysSessionInfo);
849         activeSessionInfos.addAll(infos);
850 
851         mShadowRouter2Manager.setSystemRoutingSession(sysSessionInfo);
852         mShadowRouter2Manager.setRemoteSessions(infos);
853 
854         assertThat(mInfoMediaManager.getActiveMediaSession())
855                 .containsExactlyElementsIn(activeSessionInfos);
856     }
857 
858     @Test
releaseSession_packageNameIsNull_returnFalse()859     public void releaseSession_packageNameIsNull_returnFalse() {
860         mInfoMediaManager.mPackageName = null;
861 
862         assertThat(mInfoMediaManager.releaseSession()).isFalse();
863     }
864 
865     @Test
releaseSession_removeSuccessfully_returnTrue()866     public void releaseSession_removeSuccessfully_returnTrue() {
867         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
868         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
869         routingSessionInfos.add(info);
870 
871         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
872         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
873 
874         assertThat(mInfoMediaManager.releaseSession()).isTrue();
875     }
876 
877     @Test
getSessionName_packageNameIsNull_returnNull()878     public void getSessionName_packageNameIsNull_returnNull() {
879         mInfoMediaManager.mPackageName = null;
880 
881         assertThat(mInfoMediaManager.getSessionName()).isNull();
882     }
883 
884     @Test
getSessionName_routeSessionInfoIsNull_returnNull()885     public void getSessionName_routeSessionInfoIsNull_returnNull() {
886         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
887         final RoutingSessionInfo info = null;
888         routingSessionInfos.add(info);
889 
890         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
891 
892         assertThat(mInfoMediaManager.getSessionName()).isNull();
893     }
894 
895     @Test
getSessionName_containPackageName_returnName()896     public void getSessionName_containPackageName_returnName() {
897         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
898         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
899         routingSessionInfos.add(info);
900 
901         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
902         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
903         when(info.getName()).thenReturn(TEST_NAME);
904 
905         assertThat(mInfoMediaManager.getSessionName()).isEqualTo(TEST_NAME);
906     }
907 
908     @Test
onTransferFailed_notDispatchOnRequestFailed()909     public void onTransferFailed_notDispatchOnRequestFailed() {
910         mInfoMediaManager.registerCallback(mCallback);
911 
912         mInfoMediaManager.mMediaRouterCallback.onTransferFailed(null, null);
913 
914         verify(mCallback, never()).onRequestFailed(REASON_UNKNOWN_ERROR);
915     }
916 
917     @Test
onRequestFailed_shouldDispatchOnRequestFailed()918     public void onRequestFailed_shouldDispatchOnRequestFailed() {
919         mInfoMediaManager.registerCallback(mCallback);
920 
921         mInfoMediaManager.mMediaRouterCallback.onRequestFailed(REASON_NETWORK_ERROR);
922 
923         verify(mCallback).onRequestFailed(REASON_NETWORK_ERROR);
924     }
925 
926     @Test
onTransferred_getAvailableRoutes_shouldAddMediaDevice()927     public void onTransferred_getAvailableRoutes_shouldAddMediaDevice() {
928         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
929         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
930         routingSessionInfos.add(sessionInfo);
931         final List<String> selectedRoutes = new ArrayList<>();
932         selectedRoutes.add(TEST_ID);
933         when(sessionInfo.getSelectedRoutes()).thenReturn(selectedRoutes);
934         mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
935 
936         final MediaRoute2Info info = mock(MediaRoute2Info.class);
937         mInfoMediaManager.registerCallback(mCallback);
938 
939         when(info.getDeduplicationIds()).thenReturn(Set.of());
940         when(info.getId()).thenReturn(TEST_ID);
941         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
942 
943         final List<MediaRoute2Info> routes = new ArrayList<>();
944         routes.add(info);
945         mShadowRouter2Manager.setTransferableRoutes(routes);
946 
947         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
948         assertThat(mediaDevice).isNull();
949 
950         mInfoMediaManager.mMediaRouterCallback.onTransferred(sessionInfo, sessionInfo);
951 
952         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
953         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
954         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice);
955         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
956         verify(mCallback).onConnectedDeviceChanged(TEST_ID);
957     }
958 
959     @Test
onTransferred_buildAllRoutes_shouldAddMediaDevice()960     public void onTransferred_buildAllRoutes_shouldAddMediaDevice() {
961         final MediaRoute2Info info = mock(MediaRoute2Info.class);
962         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
963         mInfoMediaManager.registerCallback(mCallback);
964 
965         when(info.getId()).thenReturn(TEST_ID);
966         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
967         when(info.isSystemRoute()).thenReturn(true);
968 
969         final List<MediaRoute2Info> routes = new ArrayList<>();
970         routes.add(info);
971         mShadowRouter2Manager.setAllRoutes(routes);
972 
973         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
974         assertThat(mediaDevice).isNull();
975 
976         mInfoMediaManager.mPackageName = "";
977         mInfoMediaManager.mMediaRouterCallback.onTransferred(sessionInfo, sessionInfo);
978 
979         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
980         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
981         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
982         verify(mCallback).onConnectedDeviceChanged(null);
983     }
984 
985     @Test
onSessionUpdated_shouldDispatchDeviceListAdded()986     public void onSessionUpdated_shouldDispatchDeviceListAdded() {
987         final MediaRoute2Info info = mock(MediaRoute2Info.class);
988         when(info.getId()).thenReturn(TEST_ID);
989         when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
990         when(info.isSystemRoute()).thenReturn(true);
991 
992         final List<MediaRoute2Info> routes = new ArrayList<>();
993         routes.add(info);
994         mShadowRouter2Manager.setAllRoutes(routes);
995 
996         mInfoMediaManager.mPackageName = "";
997         mInfoMediaManager.registerCallback(mCallback);
998 
999         mInfoMediaManager.mMediaRouterCallback.onSessionUpdated(mock(RoutingSessionInfo.class));
1000 
1001         verify(mCallback).onDeviceListAdded(any());
1002     }
1003 
1004     @Test
addMediaDevice_verifyDeviceTypeCanCorrespondToMediaDevice()1005     public void addMediaDevice_verifyDeviceTypeCanCorrespondToMediaDevice() {
1006         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
1007         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
1008                 mock(CachedBluetoothDeviceManager.class);
1009         final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
1010 
1011         when(route2Info.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
1012         when(route2Info.getId()).thenReturn(TEST_ID);
1013         mInfoMediaManager.addMediaDevice(route2Info);
1014         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof InfoMediaDevice).isTrue();
1015 
1016         when(route2Info.getType()).thenReturn(TYPE_USB_DEVICE);
1017         when(route2Info.getId()).thenReturn(TEST_ID);
1018         mInfoMediaManager.mMediaDevices.clear();
1019         mInfoMediaManager.addMediaDevice(route2Info);
1020         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
1021 
1022         when(route2Info.getType()).thenReturn(TYPE_WIRED_HEADSET);
1023         when(route2Info.getId()).thenReturn(TEST_ID);
1024         mInfoMediaManager.mMediaDevices.clear();
1025         mInfoMediaManager.addMediaDevice(route2Info);
1026         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
1027 
1028         when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
1029         when(route2Info.getAddress()).thenReturn("00:00:00:00:00:00");
1030         when(route2Info.getId()).thenReturn(TEST_ID);
1031         when(mLocalBluetoothManager.getCachedDeviceManager())
1032                 .thenReturn(cachedBluetoothDeviceManager);
1033         when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
1034                 .thenReturn(cachedDevice);
1035         mInfoMediaManager.mMediaDevices.clear();
1036         mInfoMediaManager.addMediaDevice(route2Info);
1037         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof BluetoothMediaDevice).isTrue();
1038 
1039         when(route2Info.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
1040         mInfoMediaManager.mMediaDevices.clear();
1041         mInfoMediaManager.addMediaDevice(route2Info);
1042         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
1043     }
1044 
1045     @Test
addMediaDevice_cachedBluetoothDeviceIsNull_shouldNotAdded()1046     public void addMediaDevice_cachedBluetoothDeviceIsNull_shouldNotAdded() {
1047         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
1048         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
1049                 mock(CachedBluetoothDeviceManager.class);
1050 
1051         when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
1052         when(route2Info.getAddress()).thenReturn("00:00:00:00:00:00");
1053         when(mLocalBluetoothManager.getCachedDeviceManager())
1054                 .thenReturn(cachedBluetoothDeviceManager);
1055         when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
1056                 .thenReturn(null);
1057 
1058         mInfoMediaManager.mMediaDevices.clear();
1059         mInfoMediaManager.addMediaDevice(route2Info);
1060 
1061         assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0);
1062     }
1063 
1064     @Test
addMediaDevice_deviceIncludedInSelectedDevices_shouldSetAsCurrentConnected()1065     public void addMediaDevice_deviceIncludedInSelectedDevices_shouldSetAsCurrentConnected() {
1066         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
1067         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
1068                 mock(CachedBluetoothDeviceManager.class);
1069         final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
1070         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
1071         final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
1072         routingSessionInfos.add(sessionInfo);
1073 
1074         when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME)).thenReturn(routingSessionInfos);
1075         when(sessionInfo.getSelectedRoutes()).thenReturn(ImmutableList.of(TEST_ID));
1076         when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
1077         when(route2Info.getAddress()).thenReturn("00:00:00:00:00:00");
1078         when(route2Info.getId()).thenReturn(TEST_ID);
1079         when(mLocalBluetoothManager.getCachedDeviceManager())
1080                 .thenReturn(cachedBluetoothDeviceManager);
1081         when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
1082                 .thenReturn(cachedDevice);
1083         mInfoMediaManager.mRouterManager = mRouterManager;
1084 
1085         mInfoMediaManager.mMediaDevices.clear();
1086         mInfoMediaManager.addMediaDevice(route2Info);
1087 
1088         MediaDevice device = mInfoMediaManager.mMediaDevices.get(0);
1089 
1090         assertThat(device instanceof BluetoothMediaDevice).isTrue();
1091         assertThat(device.getState()).isEqualTo(STATE_SELECTED);
1092         assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(device);
1093     }
1094 
1095     @Test
shouldDisableMediaOutput_infosIsEmpty_returnsTrue()1096     public void shouldDisableMediaOutput_infosIsEmpty_returnsTrue() {
1097         mShadowRouter2Manager.setTransferableRoutes(new ArrayList<>());
1098 
1099         assertThat(mInfoMediaManager.shouldDisableMediaOutput("test")).isTrue();
1100     }
1101 
1102     @Test
shouldDisableMediaOutput_infosSizeEqual1_returnsFalse()1103     public void shouldDisableMediaOutput_infosSizeEqual1_returnsFalse() {
1104         final MediaRoute2Info info = mock(MediaRoute2Info.class);
1105         final List<MediaRoute2Info> infos = new ArrayList<>();
1106         infos.add(info);
1107         mShadowRouter2Manager.setTransferableRoutes(infos);
1108 
1109         when(info.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
1110 
1111         assertThat(mInfoMediaManager.shouldDisableMediaOutput("test")).isFalse();
1112     }
1113 
1114     @Test
shouldDisableMediaOutput_infosSizeEqual1AndNotCastDevice_returnsFalse()1115     public void shouldDisableMediaOutput_infosSizeEqual1AndNotCastDevice_returnsFalse() {
1116         final MediaRoute2Info info = mock(MediaRoute2Info.class);
1117         final List<MediaRoute2Info> infos = new ArrayList<>();
1118         infos.add(info);
1119         mShadowRouter2Manager.setTransferableRoutes(infos);
1120 
1121         when(info.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
1122 
1123         assertThat(mInfoMediaManager.shouldDisableMediaOutput("test")).isFalse();
1124     }
1125 
1126 
1127     @Test
shouldDisableMediaOutput_infosSizeOverThan1_returnsFalse()1128     public void shouldDisableMediaOutput_infosSizeOverThan1_returnsFalse() {
1129         final MediaRoute2Info info = mock(MediaRoute2Info.class);
1130         final MediaRoute2Info info2 = mock(MediaRoute2Info.class);
1131         final List<MediaRoute2Info> infos = new ArrayList<>();
1132         infos.add(info);
1133         infos.add(info2);
1134         mShadowRouter2Manager.setTransferableRoutes(infos);
1135 
1136         when(info.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
1137         when(info2.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
1138 
1139         assertThat(mInfoMediaManager.shouldDisableMediaOutput("test")).isFalse();
1140     }
1141 }
1142