1 /* 2 * Copyright (C) 2015 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.tv.menu; 17 18 import static androidx.test.InstrumentationRegistry.getInstrumentation; 19 import static com.google.common.truth.Truth.assertWithMessage; 20 import static org.junit.Assert.fail; 21 22 import android.media.tv.TvTrackInfo; 23 import android.os.SystemClock; 24 import android.text.TextUtils; 25 import androidx.test.filters.MediumTest; 26 import androidx.test.runner.AndroidJUnit4; 27 import com.android.tv.testing.activities.BaseMainActivityTestCase; 28 import com.android.tv.testing.constants.Constants; 29 import com.android.tv.testing.testinput.ChannelState; 30 import com.android.tv.testing.testinput.ChannelStateData; 31 import com.android.tv.testing.testinput.TvTestInputConstants; 32 import java.util.Collections; 33 import java.util.List; 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 /** Tests for {@link TvOptionsRowAdapter}. */ 39 @MediumTest 40 @RunWith(AndroidJUnit4.class) 41 public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase { 42 private static final int WAIT_TRACK_EVENT_TIMEOUT_MS = 300; 43 public static final int TRACK_CHECK_INTERVAL_MS = 10; 44 45 // TODO: Refactor TvOptionsRowAdapter so it does not rely on MainActivity 46 private TvOptionsRowAdapter mTvOptionsRowAdapter; 47 48 @Override 49 @Before setUp()50 public void setUp() { 51 super.setUp(); 52 mTvOptionsRowAdapter = new TvOptionsRowAdapter(mActivity, Collections.emptyList()); 53 tuneToChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY); 54 waitUntilAudioTracksHaveSize(1); 55 waitUntilAudioTrackSelected(ChannelState.DEFAULT.getSelectedAudioTrackId()); 56 // update should be called on the main thread to avoid the multi-thread problem. 57 getInstrumentation() 58 .runOnMainSync( 59 new Runnable() { 60 @Override 61 public void run() { 62 mTvOptionsRowAdapter.update(); 63 } 64 }); 65 } 66 67 @Test testUpdateAudioAction_2tracks()68 public void testUpdateAudioAction_2tracks() { 69 ChannelStateData data = new ChannelStateData(); 70 data.mTvTrackInfos.add(Constants.GENERIC_AUDIO_TRACK); 71 updateThenTune(data, TvTestInputConstants.CH_2); 72 waitUntilAudioTracksHaveSize(2); 73 waitUntilAudioTrackSelected(Constants.EN_STEREO_AUDIO_TRACK.getId()); 74 75 boolean result = mTvOptionsRowAdapter.updateMultiAudioAction(); 76 assertWithMessage("update Action had change").that(result).isTrue(); 77 assertWithMessage("Multi Audio enabled") 78 .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled()) 79 .isTrue(); 80 } 81 82 @Test testUpdateAudioAction_1track()83 public void testUpdateAudioAction_1track() { 84 ChannelStateData data = new ChannelStateData(); 85 data.mTvTrackInfos.clear(); 86 data.mTvTrackInfos.add(Constants.GENERIC_AUDIO_TRACK); 87 data.mSelectedVideoTrackId = null; 88 data.mSelectedAudioTrackId = Constants.GENERIC_AUDIO_TRACK.getId(); 89 updateThenTune(data, TvTestInputConstants.CH_2); 90 waitUntilAudioTracksHaveSize(1); 91 waitUntilAudioTrackSelected(Constants.GENERIC_AUDIO_TRACK.getId()); 92 93 boolean result = mTvOptionsRowAdapter.updateMultiAudioAction(); 94 assertWithMessage("update Action had change").that(result).isTrue(); 95 assertWithMessage("Multi Audio enabled") 96 .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled()) 97 .isFalse(); 98 } 99 100 @Test testUpdateAudioAction_noTracks()101 public void testUpdateAudioAction_noTracks() { 102 ChannelStateData data = new ChannelStateData(); 103 data.mTvTrackInfos.clear(); 104 data.mTvTrackInfos.add(ChannelState.DEFAULT_VIDEO_TRACK); 105 data.mSelectedVideoTrackId = ChannelState.DEFAULT_VIDEO_TRACK.getId(); 106 data.mSelectedAudioTrackId = null; 107 updateThenTune(data, TvTestInputConstants.CH_2); 108 // Wait for the video tracks, because there's no audio track. 109 waitUntilVideoTracksHaveSize(1); 110 waitUntilVideoTrackSelected(data.mSelectedVideoTrackId); 111 112 boolean result = mTvOptionsRowAdapter.updateMultiAudioAction(); 113 assertWithMessage("update Action had change").that(result).isTrue(); 114 assertWithMessage("Multi Audio enabled") 115 .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled()) 116 .isFalse(); 117 } 118 waitUntilAudioTracksHaveSize(int expected)119 private void waitUntilAudioTracksHaveSize(int expected) { 120 waitUntilTracksHaveSize(TvTrackInfo.TYPE_AUDIO, expected); 121 } 122 waitUntilVideoTracksHaveSize(int expected)123 private void waitUntilVideoTracksHaveSize(int expected) { 124 waitUntilTracksHaveSize(TvTrackInfo.TYPE_VIDEO, expected); 125 } 126 waitUntilTracksHaveSize(int trackType, int expected)127 private void waitUntilTracksHaveSize(int trackType, int expected) { 128 long start = SystemClock.elapsedRealtime(); 129 int size = -1; 130 while (SystemClock.elapsedRealtime() < start + WAIT_TRACK_EVENT_TIMEOUT_MS) { 131 getInstrumentation().waitForIdleSync(); 132 List<TvTrackInfo> tracks = mActivity.getTracks(trackType); 133 if (tracks != null) { 134 size = tracks.size(); 135 if (size == expected) { 136 return; 137 } 138 } 139 SystemClock.sleep(TRACK_CHECK_INTERVAL_MS); 140 } 141 fail( 142 "Waited for " 143 + WAIT_TRACK_EVENT_TIMEOUT_MS 144 + " milliseconds for track size to be " 145 + expected 146 + " but was " 147 + size); 148 } 149 waitUntilAudioTrackSelected(String trackId)150 private void waitUntilAudioTrackSelected(String trackId) { 151 waitUntilTrackSelected(TvTrackInfo.TYPE_AUDIO, trackId); 152 } 153 waitUntilVideoTrackSelected(String trackId)154 private void waitUntilVideoTrackSelected(String trackId) { 155 waitUntilTrackSelected(TvTrackInfo.TYPE_VIDEO, trackId); 156 } 157 waitUntilTrackSelected(int trackType, String trackId)158 private void waitUntilTrackSelected(int trackType, String trackId) { 159 long start = SystemClock.elapsedRealtime(); 160 String selectedTrackId = null; 161 while (SystemClock.elapsedRealtime() < start + WAIT_TRACK_EVENT_TIMEOUT_MS) { 162 getInstrumentation().waitForIdleSync(); 163 selectedTrackId = mActivity.getSelectedTrack(trackType); 164 if (TextUtils.equals(selectedTrackId, trackId)) { 165 return; 166 } 167 SystemClock.sleep(TRACK_CHECK_INTERVAL_MS); 168 } 169 fail( 170 "Waited for " 171 + WAIT_TRACK_EVENT_TIMEOUT_MS 172 + " milliseconds for track ID to be " 173 + trackId 174 + " but was " 175 + selectedTrackId); 176 } 177 } 178