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