1 /*
2  * Copyright (C) 2020 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 package com.android.settings.media;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.doReturn;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.spy;
24 import static org.mockito.Mockito.when;
25 
26 import android.content.Context;
27 import android.media.AudioAttributes;
28 import android.media.VolumeProvider;
29 import android.media.session.MediaController;
30 import android.media.session.MediaSessionManager;
31 import android.media.session.PlaybackState;
32 
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.Mock;
37 import org.mockito.MockitoAnnotations;
38 import org.robolectric.RobolectricTestRunner;
39 import org.robolectric.RuntimeEnvironment;
40 
41 import java.util.ArrayList;
42 import java.util.List;
43 
44 @RunWith(RobolectricTestRunner.class)
45 public class MediaOutputUtilsTest {
46 
47     @Mock
48     private MediaSessionManager mMediaSessionManager;
49     @Mock
50     private MediaController mMediaController;
51 
52     private Context mContext;
53     private List<MediaController> mMediaControllers = new ArrayList<>();
54     private PlaybackState mPlaybackState;
55     private MediaController.PlaybackInfo mPlaybackInfo;
56 
57     @Before
setUp()58     public void setUp() {
59         MockitoAnnotations.initMocks(this);
60 
61         mContext = spy(RuntimeEnvironment.application);
62         doReturn(mMediaSessionManager).when(mContext).getSystemService(MediaSessionManager.class);
63         mMediaControllers.add(mMediaController);
64         doReturn(mMediaControllers).when(mMediaSessionManager).getActiveSessions(any());
65     }
66 
67     @Test
getActiveLocalMediaController_localMediaPlaying_returnController()68     public void getActiveLocalMediaController_localMediaPlaying_returnController() {
69         initPlayback(PlaybackState.STATE_PLAYING);
70 
71         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
72         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
73 
74         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isEqualTo(
75                 mMediaController);
76     }
77 
78     @Test
getActiveLocalMediaController_localMediaPause_returnController()79     public void getActiveLocalMediaController_localMediaPause_returnController() {
80         initPlayback(PlaybackState.STATE_PAUSED);
81 
82         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
83         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
84 
85         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isEqualTo(
86                 mMediaController);
87     }
88 
89     @Test
getActiveLocalMediaController_remoteMediaPlaying_returnNull()90     public void getActiveLocalMediaController_remoteMediaPlaying_returnNull() {
91         mPlaybackInfo = new MediaController.PlaybackInfo(
92                 MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
93                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
94                 100,
95                 10,
96                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
97                 null);
98         mPlaybackState = new PlaybackState.Builder()
99                 .setState(PlaybackState.STATE_PLAYING, 0, 1)
100                 .build();
101 
102         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
103         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
104 
105         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull();
106     }
107 
108     @Test
getActiveLocalMediaController_localMediaStopped_returnNull()109     public void getActiveLocalMediaController_localMediaStopped_returnNull() {
110         mPlaybackInfo = new MediaController.PlaybackInfo(
111                 MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
112                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
113                 100,
114                 10,
115                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
116                 null);
117         mPlaybackState = new PlaybackState.Builder()
118                 .setState(PlaybackState.STATE_STOPPED, 0, 1)
119                 .build();
120 
121         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
122         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
123 
124         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull();
125     }
126 
127     @Test
getActiveLocalMediaController_localMediaNone_returnNull()128     public void getActiveLocalMediaController_localMediaNone_returnNull() {
129         mPlaybackInfo = new MediaController.PlaybackInfo(
130                 MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
131                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
132                 100,
133                 10,
134                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
135                 null);
136         mPlaybackState = new PlaybackState.Builder()
137                 .setState(PlaybackState.STATE_NONE, 0, 1)
138                 .build();
139 
140         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
141         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
142 
143         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull();
144     }
145 
146     @Test
getActiveLocalMediaController_localMediaError_returnNull()147     public void getActiveLocalMediaController_localMediaError_returnNull() {
148         mPlaybackInfo = new MediaController.PlaybackInfo(
149                 MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
150                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
151                 100,
152                 10,
153                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
154                 null);
155         mPlaybackState = new PlaybackState.Builder()
156                 .setState(PlaybackState.STATE_ERROR, 0, 1)
157                 .build();
158 
159         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
160         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
161 
162         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull();
163     }
164 
165     @Test
getActiveLocalMediaController_bothHaveRemoteMediaAndLocalMedia_returnNull()166     public void getActiveLocalMediaController_bothHaveRemoteMediaAndLocalMedia_returnNull() {
167         mMediaControllers.clear();
168         final MediaController.PlaybackInfo playbackInfo = new MediaController.PlaybackInfo(
169                 MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
170                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
171                 100,
172                 10,
173                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
174                 null);
175         final PlaybackState playbackState = new PlaybackState.Builder()
176                 .setState(PlaybackState.STATE_PLAYING, 0, 1)
177                 .build();
178         final MediaController remoteMediaController = mock(MediaController.class);
179 
180         mMediaControllers.add(remoteMediaController);
181         mMediaControllers.add(mMediaController);
182         initPlayback(PlaybackState.STATE_PLAYING);
183 
184         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
185         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
186         when(remoteMediaController.getPlaybackInfo()).thenReturn(playbackInfo);
187         when(remoteMediaController.getPlaybackState()).thenReturn(playbackState);
188 
189         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull();
190     }
191 
192     @Test
getActiveLocalMediaController_bothHaveLocalMediaAndRemoteMedia_returnNull()193     public void getActiveLocalMediaController_bothHaveLocalMediaAndRemoteMedia_returnNull() {
194         final MediaController.PlaybackInfo playbackInfo = new MediaController.PlaybackInfo(
195                 MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE,
196                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
197                 100,
198                 10,
199                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
200                 null);
201         final PlaybackState playbackState = new PlaybackState.Builder()
202                 .setState(PlaybackState.STATE_PLAYING, 0, 1)
203                 .build();
204         final MediaController remoteMediaController = mock(MediaController.class);
205 
206         mMediaControllers.add(remoteMediaController);
207         initPlayback(PlaybackState.STATE_PLAYING);
208 
209         when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
210         when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
211         when(remoteMediaController.getPlaybackInfo()).thenReturn(playbackInfo);
212         when(remoteMediaController.getPlaybackState()).thenReturn(playbackState);
213 
214         assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull();
215     }
216 
initPlayback(int playbackState)217     private void initPlayback(int playbackState) {
218         mPlaybackInfo = new MediaController.PlaybackInfo(
219                 MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
220                 VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
221                 100,
222                 10,
223                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
224                 null);
225         mPlaybackState = new PlaybackState.Builder()
226                 .setState(playbackState, 0, 1)
227                 .build();
228     }
229 }
230