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 package com.android.tv.audio; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import android.app.Activity; 21 import android.media.AudioManager; 22 import android.os.Build; 23 24 import com.android.tv.testing.constants.ConfigConstants; 25 import com.android.tv.ui.api.TunableTvViewPlayingApi; 26 27 import org.junit.Before; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.robolectric.Robolectric; 31 import org.robolectric.RobolectricTestRunner; 32 import org.robolectric.RuntimeEnvironment; 33 import org.robolectric.Shadows; 34 import org.robolectric.annotation.Config; 35 36 /** Tests for {@link AudioManagerHelper}. */ 37 @RunWith(RobolectricTestRunner.class) 38 @Config(sdk = ConfigConstants.SDK) 39 public class AudioManagerHelperTest { 40 41 private AudioManagerHelper mAudioManagerHelper; 42 private TestTvView mTvView; 43 private AudioManager mAudioManager; 44 45 @Before setup()46 public void setup() { 47 Activity testActivity = Robolectric.buildActivity(Activity.class).get(); 48 mTvView = new TestTvView(); 49 mAudioManager = RuntimeEnvironment.application.getSystemService(AudioManager.class); 50 51 mAudioManagerHelper = new AudioManagerHelper(testActivity, mTvView); 52 } 53 54 @Test onAudioFocusChange_none_noTimeShift()55 public void onAudioFocusChange_none_noTimeShift() { 56 mTvView.mTimeShiftAvailable = false; 57 58 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_NONE); 59 60 assertThat(mTvView.mPaused).isNull(); 61 assertThat(mTvView.mVolume).isZero(); 62 } 63 64 @Test onAudioFocusChange_none_TimeShift()65 public void onAudioFocusChange_none_TimeShift() { 66 mTvView.mTimeShiftAvailable = true; 67 68 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_NONE); 69 70 assertThat(mTvView.mPaused).isTrue(); 71 assertThat(mTvView.mVolume).isNull(); 72 } 73 74 @Test onAudioFocusChange_gain_noTimeShift()75 public void onAudioFocusChange_gain_noTimeShift() { 76 mTvView.mTimeShiftAvailable = false; 77 78 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN); 79 80 assertThat(mTvView.mPaused).isNull(); 81 assertThat(mTvView.mVolume).isEqualTo(1.0f); 82 } 83 84 @Test onAudioFocusChange_gain_timeShift()85 public void onAudioFocusChange_gain_timeShift() { 86 mTvView.mTimeShiftAvailable = true; 87 88 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN); 89 90 assertThat(mTvView.mPaused).isFalse(); 91 assertThat(mTvView.mVolume).isNull(); 92 } 93 94 @Test onAudioFocusChange_loss_noTimeShift()95 public void onAudioFocusChange_loss_noTimeShift() { 96 mTvView.mTimeShiftAvailable = false; 97 98 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS); 99 100 assertThat(mTvView.mPaused).isNull(); 101 assertThat(mTvView.mVolume).isEqualTo(0.0f); 102 } 103 104 @Test onAudioFocusChange_loss_timeShift()105 public void onAudioFocusChange_loss_timeShift() { 106 mTvView.mTimeShiftAvailable = true; 107 108 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS); 109 110 assertThat(mTvView.mPaused).isTrue(); 111 assertThat(mTvView.mVolume).isNull(); 112 } 113 114 @Test onAudioFocusChange_lossTransient_noTimeShift()115 public void onAudioFocusChange_lossTransient_noTimeShift() { 116 mTvView.mTimeShiftAvailable = false; 117 118 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT); 119 120 assertThat(mTvView.mPaused).isNull(); 121 assertThat(mTvView.mVolume).isEqualTo(0.0f); 122 } 123 124 @Test onAudioFocusChange_lossTransient_timeShift()125 public void onAudioFocusChange_lossTransient_timeShift() { 126 mTvView.mTimeShiftAvailable = true; 127 128 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT); 129 130 assertThat(mTvView.mPaused).isTrue(); 131 assertThat(mTvView.mVolume).isNull(); 132 } 133 134 @Test onAudioFocusChange_lossTransientCanDuck_noTimeShift()135 public void onAudioFocusChange_lossTransientCanDuck_noTimeShift() { 136 mTvView.mTimeShiftAvailable = false; 137 138 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); 139 140 assertThat(mTvView.mPaused).isNull(); 141 assertThat(mTvView.mVolume).isEqualTo(0.3f); 142 } 143 144 @Test onAudioFocusChange_lossTransientCanDuck_timeShift()145 public void onAudioFocusChange_lossTransientCanDuck_timeShift() { 146 mTvView.mTimeShiftAvailable = true; 147 148 mAudioManagerHelper.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); 149 150 assertThat(mTvView.mPaused).isTrue(); 151 assertThat(mTvView.mVolume).isNull(); 152 } 153 154 @Test 155 @Config(sdk = {ConfigConstants.SDK, Build.VERSION_CODES.O}) requestAudioFocus_granted()156 public void requestAudioFocus_granted() { 157 Shadows.shadowOf(mAudioManager) 158 .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); 159 mAudioManagerHelper.requestAudioFocus(); 160 161 assertThat(mTvView.mPaused).isNull(); 162 assertThat(mTvView.mVolume).isEqualTo(1.0f); 163 } 164 165 @Test 166 @Config(sdk = {ConfigConstants.SDK, Build.VERSION_CODES.O}) requestAudioFocus_failed()167 public void requestAudioFocus_failed() { 168 Shadows.shadowOf(mAudioManager) 169 .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_FAILED); 170 171 mAudioManagerHelper.requestAudioFocus(); 172 173 assertThat(mTvView.mPaused).isNull(); 174 assertThat(mTvView.mVolume).isZero(); 175 } 176 177 @Test 178 @Config(sdk = {ConfigConstants.SDK, Build.VERSION_CODES.O}) requestAudioFocus_delayed()179 public void requestAudioFocus_delayed() { 180 Shadows.shadowOf(mAudioManager) 181 .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_DELAYED); 182 183 mAudioManagerHelper.requestAudioFocus(); 184 185 assertThat(mTvView.mPaused).isNull(); 186 assertThat(mTvView.mVolume).isZero(); 187 } 188 189 @Test setVolumeByAudioFocusStatus_started()190 public void setVolumeByAudioFocusStatus_started() { 191 mAudioManagerHelper.setVolumeByAudioFocusStatus(); 192 193 assertThat(mTvView.mPaused).isNull(); 194 assertThat(mTvView.mVolume).isZero(); 195 } 196 197 @Test setVolumeByAudioFocusStatus_notStarted()198 public void setVolumeByAudioFocusStatus_notStarted() { 199 mTvView.mStarted = false; 200 mAudioManagerHelper.setVolumeByAudioFocusStatus(); 201 202 assertThat(mTvView.mPaused).isNull(); 203 assertThat(mTvView.mVolume).isNull(); 204 } 205 206 private static class TestTvView implements TunableTvViewPlayingApi { 207 private boolean mStarted = true; 208 private boolean mTimeShiftAvailable = false; 209 private Float mVolume = null; 210 private Boolean mPaused = null; 211 212 @Override isPlaying()213 public boolean isPlaying() { 214 return mStarted; 215 } 216 217 @Override setStreamVolume(float volume)218 public void setStreamVolume(float volume) { 219 mVolume = volume; 220 } 221 222 @Override setTimeShiftListener(TimeShiftListener listener)223 public void setTimeShiftListener(TimeShiftListener listener) { 224 throw new UnsupportedOperationException(); 225 } 226 227 @Override isTimeShiftAvailable()228 public boolean isTimeShiftAvailable() { 229 return mTimeShiftAvailable; 230 } 231 232 @Override timeShiftPlay()233 public void timeShiftPlay() { 234 mPaused = false; 235 } 236 237 @Override timeShiftPause()238 public void timeShiftPause() { 239 mPaused = true; 240 } 241 242 @Override timeShiftRewind(int speed)243 public void timeShiftRewind(int speed) { 244 throw new UnsupportedOperationException(); 245 } 246 247 @Override timeShiftFastForward(int speed)248 public void timeShiftFastForward(int speed) { 249 throw new UnsupportedOperationException(); 250 } 251 252 @Override timeShiftSeekTo(long timeMs)253 public void timeShiftSeekTo(long timeMs) { 254 throw new UnsupportedOperationException(); 255 } 256 257 @Override timeShiftGetCurrentPositionMs()258 public long timeShiftGetCurrentPositionMs() { 259 throw new UnsupportedOperationException(); 260 } 261 } 262 } 263