1 /* 2 * Copyright (C) 2018 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.media.tv.TvTrackInfo; 22 import android.os.Bundle; 23 import android.view.LayoutInflater; 24 25 import com.android.tv.common.flags.impl.DefaultLegacyFlags; 26 import com.android.tv.data.ProgramDataManager; 27 import com.android.tv.data.StreamInfo; 28 import com.android.tv.testing.TestSingletonApp; 29 import com.android.tv.testing.TvRobolectricTestRunner; 30 import com.android.tv.testing.constants.ConfigConstants; 31 import com.android.tv.ui.TunableTvView; 32 import com.android.tv.util.TvInputManagerHelper; 33 34 import java.util.Arrays; 35 import java.util.List; 36 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 import org.robolectric.Robolectric; 41 import org.robolectric.RuntimeEnvironment; 42 import org.robolectric.annotation.Config; 43 import org.robolectric.shadow.api.Shadow; 44 45 import java.util.Arrays; 46 47 /** Tests for {@link TunableTvView} */ 48 @RunWith(TvRobolectricTestRunner.class) 49 @Config( 50 sdk = ConfigConstants.SDK, 51 application = TestSingletonApp.class, 52 shadows = {ShadowTvView.class}) 53 public class MainActivityRoboTest { 54 private ShadowTvView mShadowTvView; 55 private FakeMainActivity mMainActivity; 56 57 @Before setUp()58 public void setUp() { 59 mMainActivity = Robolectric.buildActivity(FakeMainActivity.class).create().get(); 60 mShadowTvView = Shadow.extract(mMainActivity.getTvView().getTvView()); 61 mShadowTvView.listener = mMainActivity.getListener(); 62 } 63 64 @Test testSelectAudioTrack_autoSelect()65 public void testSelectAudioTrack_autoSelect() { 66 mShadowTvView.mAudioTrackCountChanged = false; 67 setTracks( 68 TvTrackInfo.TYPE_AUDIO, 69 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 1", "EN"), 70 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 1", "FR")); 71 mMainActivity.selectAudioTrack("FR audio 1"); 72 assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 1"); 73 74 setTracks( 75 TvTrackInfo.TYPE_AUDIO, 76 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 2", "EN"), 77 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 2", "FR"), 78 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 3", "FR")); 79 mMainActivity.applyMultiAudio(null); 80 // FR audio 2 is selected according the previously selected track. 81 assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 2"); 82 } 83 84 @Test testSelectAudioTrack_audioTrackCountChanged()85 public void testSelectAudioTrack_audioTrackCountChanged() { 86 mShadowTvView.mAudioTrackCountChanged = true; 87 setTracks( 88 TvTrackInfo.TYPE_AUDIO, 89 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 1", "EN"), 90 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 1", "FR")); 91 mMainActivity.selectAudioTrack("FR audio 1"); 92 assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 1"); 93 94 setTracks( 95 TvTrackInfo.TYPE_AUDIO, 96 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 2", "EN"), 97 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 2", "FR"), 98 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 3", "FR")); 99 mMainActivity.selectAudioTrack("FR audio 3"); 100 // FR audio 3 is selected even if the track info has been changed 101 assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 3"); 102 } 103 104 @Test testSelectAudioTrack_audioTrackCountNotChanged()105 public void testSelectAudioTrack_audioTrackCountNotChanged() { 106 mShadowTvView.mAudioTrackCountChanged = false; 107 setTracks( 108 TvTrackInfo.TYPE_AUDIO, 109 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 1", "EN"), 110 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 1", "FR")); 111 mMainActivity.selectAudioTrack("FR audio 1"); 112 assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 1"); 113 114 setTracks( 115 TvTrackInfo.TYPE_AUDIO, 116 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "EN audio 2", "EN"), 117 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 2", "FR"), 118 buildTrackForTesting(TvTrackInfo.TYPE_AUDIO, "FR audio 3", "FR")); 119 mMainActivity.selectAudioTrack("FR audio 3"); 120 assertThat(mMainActivity.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)).isEqualTo("FR audio 3"); 121 } 122 123 @Test testFindBestCaptionTrack_bestTrackMatch()124 public void testFindBestCaptionTrack_bestTrackMatch() { 125 List<TvTrackInfo> tracks = Arrays.asList( 126 buildCaptionTrackForTesting("EN subtitle 1", "EN"), 127 buildCaptionTrackForTesting("EN subtitle 2", "EN"), 128 buildCaptionTrackForTesting("FR subtitle 1", "FR"), 129 buildCaptionTrackForTesting("FR subtitle 2", "FR")); 130 List<String> preferredLanguages = Arrays.asList("DE", "FR"); 131 132 int trackIndex = 133 MainActivity.findBestCaptionTrackIndex( 134 tracks, "EN", preferredLanguages, "EN subtitle 2"); 135 assertThat(trackIndex).isEqualTo(1); 136 } 137 138 @Test testFindBestCaptionTrack_selectedLanguageMatch()139 public void testFindBestCaptionTrack_selectedLanguageMatch() { 140 List<TvTrackInfo> tracks = Arrays.asList( 141 buildCaptionTrackForTesting("EN subtitle 1", "EN"), 142 buildCaptionTrackForTesting("EN subtitle 2", "EN"), 143 buildCaptionTrackForTesting("FR subtitle 1", "FR"), 144 buildCaptionTrackForTesting("FR subtitle 2", "FR")); 145 List<String> preferredLanguages = Arrays.asList("DE", "FR"); 146 147 int trackIndex = 148 MainActivity.findBestCaptionTrackIndex( 149 tracks, "EN", preferredLanguages, "EN subtitle 3"); 150 assertThat(trackIndex).isEqualTo(0); 151 } 152 153 @Test testFindBestCaptionTrack_preferredLanguageMatch()154 public void testFindBestCaptionTrack_preferredLanguageMatch() { 155 List<TvTrackInfo> tracks = Arrays.asList( 156 buildCaptionTrackForTesting("EN subtitle 1", "EN"), 157 buildCaptionTrackForTesting("EN subtitle 2", "EN"), 158 buildCaptionTrackForTesting("FR subtitle 1", "FR"), 159 buildCaptionTrackForTesting("FR subtitle 2", "FR")); 160 List<String> preferredLanguages = Arrays.asList("DE", "FR"); 161 162 int trackIndex = 163 MainActivity.findBestCaptionTrackIndex( 164 tracks, "JA", preferredLanguages, "JA subtitle 4"); 165 assertThat(trackIndex).isEqualTo(2); 166 } 167 168 @Test testFindBestCaptionTrack_higherPriorityPreferredLanguageMatch()169 public void testFindBestCaptionTrack_higherPriorityPreferredLanguageMatch() { 170 List<TvTrackInfo> tracks = Arrays.asList( 171 buildCaptionTrackForTesting("EN subtitle 1", "EN"), 172 buildCaptionTrackForTesting("EN subtitle 2", "EN"), 173 buildCaptionTrackForTesting("FR subtitle 1", "FR"), 174 buildCaptionTrackForTesting("FR subtitle 2", "FR")); 175 List<String> preferredLanguages = Arrays.asList("FR", "EN"); 176 177 int trackIndex = 178 MainActivity.findBestCaptionTrackIndex( 179 tracks, "JA", preferredLanguages, "JA subtitle 4"); 180 assertThat(trackIndex).isEqualTo(2); 181 } 182 183 @Test testFindBestCaptionTrack_noMatch()184 public void testFindBestCaptionTrack_noMatch() { 185 List<TvTrackInfo> tracks = Arrays.asList( 186 buildCaptionTrackForTesting("EN subtitle 1", "EN"), 187 buildCaptionTrackForTesting("EN subtitle 2", "EN"), 188 buildCaptionTrackForTesting("FR subtitle 1", "FR"), 189 buildCaptionTrackForTesting("FR subtitle 2", "FR")); 190 List<String> preferredLanguages = Arrays.asList("DE", "IT"); 191 192 int trackIndex = 193 MainActivity.findBestCaptionTrackIndex( 194 tracks, "JA", preferredLanguages, "JA subtitle 4"); 195 assertThat(trackIndex).isEqualTo(0); 196 } 197 setTracks(int type, TvTrackInfo... tracks)198 private void setTracks(int type, TvTrackInfo... tracks) { 199 mShadowTvView.mTracks.put(type, Arrays.asList(tracks)); 200 mShadowTvView.mSelectedTracks.put(type, null); 201 } 202 buildTrackForTesting(int type, String id, String language)203 private TvTrackInfo buildTrackForTesting(int type, String id, String language) { 204 return new TvTrackInfo.Builder(type, id) 205 .setLanguage(language) 206 .setAudioChannelCount(0) 207 .build(); 208 } 209 buildCaptionTrackForTesting(String id, String language)210 private TvTrackInfo buildCaptionTrackForTesting(String id, String language) { 211 return new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, id) 212 .setLanguage(language) 213 .build(); 214 } 215 216 /** A {@link MainActivity} class for tests */ 217 public static class FakeMainActivity extends MainActivity { 218 private MyOnTuneListener mListener; 219 220 @Override onCreate(Bundle savedInstanceState)221 protected void onCreate(Bundle savedInstanceState) { 222 // Override onCreate() to omit unnecessary member variables 223 mTvView = 224 (TunableTvView) 225 LayoutInflater.from(RuntimeEnvironment.application) 226 .inflate(R.layout.activity_tv, null) 227 .findViewById(R.id.main_tunable_tv_view); 228 DefaultLegacyFlags legacyFlags = DefaultLegacyFlags.DEFAULT; 229 mTvView.initialize( 230 new ProgramDataManager(RuntimeEnvironment.application), 231 new TvInputManagerHelper(RuntimeEnvironment.application, legacyFlags), 232 legacyFlags); 233 mTvView.start(); 234 mListener = 235 new MyOnTuneListener() { 236 @Override 237 public void onStreamInfoChanged( 238 StreamInfo info, boolean allowAutoSelectionOfTrack) { 239 applyMultiAudio( 240 allowAutoSelectionOfTrack 241 ? null 242 : getSelectedTrack(TvTrackInfo.TYPE_AUDIO)); 243 } 244 }; 245 mTvView.setOnTuneListener(mListener); 246 } 247 getTvView()248 public TunableTvView getTvView() { 249 return mTvView; 250 } 251 getListener()252 public MyOnTuneListener getListener() { 253 return mListener; 254 } 255 } 256 } 257