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