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