1 /*
2  * Copyright (C) 2017 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.tv;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.app.PendingIntent;
22 import android.content.Intent;
23 import android.media.MediaMetadata;
24 import android.media.session.PlaybackState;
25 
26 import com.android.tv.testing.EpgTestData;
27 import com.android.tv.testing.TvRobolectricTestRunner;
28 import com.android.tv.testing.TestSingletonApp;
29 import com.android.tv.testing.constants.ConfigConstants;
30 import com.android.tv.testing.shadows.ShadowMediaSession;
31 
32 import com.google.common.collect.Maps;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.robolectric.RuntimeEnvironment;
38 import org.robolectric.annotation.Config;
39 import org.robolectric.shadow.api.Shadow;
40 
41 import java.util.Map;
42 
43 /** Tests fpr {@link MediaSessionWrapper}. */
44 @RunWith(TvRobolectricTestRunner.class)
45 @Config(
46         sdk = ConfigConstants.SDK,
47         application = TestSingletonApp.class,
48         shadows = {ShadowMediaSession.class})
49 public class MediaSessionWrapperTest {
50 
51     private static final int TEST_REQUEST_CODE = 1337;
52 
53     private ShadowMediaSession mediaSession;
54     private MediaSessionWrapper mediaSessionWrapper;
55     private PendingIntent pendingIntent;
56 
57     @Before
setUp()58     public void setUp() {
59         pendingIntent =
60                 PendingIntent.getActivity(
61                         RuntimeEnvironment.application, TEST_REQUEST_CODE, new Intent(), 0);
62         mediaSessionWrapper =
63                 new MediaSessionWrapper(RuntimeEnvironment.application, pendingIntent) {
64                     @Override
65                     void initMediaController() {
66                         // Not use MediaController for tests here because:
67                         // 1. it's not allow to shadow MediaController
68                         // 2. The Context TestSingletonApp is not an instance of Activity so
69                         // Activity.setMediaController cannot be called.
70                         // onPlaybackStateChanged() is called in #setPlaybackState instead.
71                     }
72 
73                     @Override
74                     void unregisterMediaControllerCallback() {}
75                 };
76         mediaSession = Shadow.extract(mediaSessionWrapper.getMediaSession());
77     }
78 
79     @Test
setSessionActivity()80     public void setSessionActivity() {
81         assertThat(mediaSession.mSessionActivity).isEqualTo(this.pendingIntent);
82     }
83 
84     @Test
setPlaybackState_true()85     public void setPlaybackState_true() {
86         setPlaybackState(true);
87         assertThat(mediaSession.mActive).isTrue();
88         assertThat(mediaSession.mPlaybackState.getState()).isEqualTo(PlaybackState.STATE_PLAYING);
89     }
90 
91     @Test
setPlaybackState_false()92     public void setPlaybackState_false() {
93         setPlaybackState(false);
94         assertThat(mediaSession.mActive).isFalse();
95         assertThat(mediaSession.mPlaybackState).isNull();
96     }
97 
98     @Test
setPlaybackState_trueThenFalse()99     public void setPlaybackState_trueThenFalse() {
100         setPlaybackState(true);
101         setPlaybackState(false);
102         assertThat(mediaSession.mActive).isFalse();
103         assertThat(mediaSession.mPlaybackState.getState()).isEqualTo(PlaybackState.STATE_STOPPED);
104     }
105 
106     @Test
update_channel10()107     public void update_channel10() {
108 
109         mediaSessionWrapper.update(false, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), null);
110         assertThat(asMap(mediaSession.mMediaMetadata))
111                 .containsExactly(MediaMetadata.METADATA_KEY_TITLE, "Channel TEN");
112     }
113 
114     @Test
update_blockedChannel10()115     public void update_blockedChannel10() {
116         mediaSessionWrapper.update(true, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), null);
117         assertThat(asMap(mediaSession.mMediaMetadata))
118                 .containsExactly(
119                         MediaMetadata.METADATA_KEY_TITLE,
120                         "Channel blocked",
121                         MediaMetadata.METADATA_KEY_ART,
122                         null);
123     }
124 
125     @Test
update_channel10Program2()126     public void update_channel10Program2() {
127         mediaSessionWrapper.update(
128                 false, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), EpgTestData.PROGRAM_2);
129         assertThat(asMap(mediaSession.mMediaMetadata))
130                 .containsExactly(MediaMetadata.METADATA_KEY_TITLE, "Program 2");
131     }
132 
133     @Test
update_blockedChannel10Program2()134     public void update_blockedChannel10Program2() {
135         mediaSessionWrapper.update(
136                 true, EpgTestData.toTvChannel(EpgTestData.CHANNEL_10), EpgTestData.PROGRAM_2);
137         assertThat(asMap(mediaSession.mMediaMetadata))
138                 .containsExactly(
139                         MediaMetadata.METADATA_KEY_TITLE,
140                         "Channel blocked",
141                         MediaMetadata.METADATA_KEY_ART,
142                         null);
143         // TODO(b/70559407): test async loading of images.
144     }
145 
146     @Test
release()147     public void release() {
148         mediaSessionWrapper.release();
149         assertThat(mediaSession.mReleased).isTrue();
150     }
151 
asMap(MediaMetadata mediaMetadata)152     private Map<String, Object> asMap(MediaMetadata mediaMetadata) {
153         return Maps.asMap(mediaMetadata.keySet(), key -> mediaMetadata.getString(key));
154     }
155 
setPlaybackState(boolean isPlaying)156     private void setPlaybackState(boolean isPlaying) {
157         mediaSessionWrapper.setPlaybackState(isPlaying);
158         mediaSessionWrapper
159                 .getMediaControllerCallback()
160                 .onPlaybackStateChanged(
161                         isPlaying
162                                 ? MediaSessionWrapper.MEDIA_SESSION_STATE_PLAYING
163                                 : MediaSessionWrapper.MEDIA_SESSION_STATE_STOPPED);
164     }
165 }
166