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.server.hdmi; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 23 import android.annotation.Nullable; 24 import android.content.Context; 25 import android.hardware.hdmi.HdmiDeviceInfo; 26 import android.hardware.tv.cec.V1_0.SendMessageResult; 27 import android.os.Looper; 28 import android.os.test.TestLooper; 29 import android.platform.test.annotations.Presubmit; 30 31 import androidx.test.InstrumentationRegistry; 32 import androidx.test.filters.SmallTest; 33 34 import org.junit.Before; 35 import org.junit.Ignore; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 import org.junit.runners.JUnit4; 39 40 import java.util.Collections; 41 42 /** Tests for {@link SystemAudioInitiationActionFromAvr} */ 43 @SmallTest 44 @Presubmit 45 @RunWith(JUnit4.class) 46 public class SystemAudioInitiationActionFromAvrTest { 47 48 private HdmiCecLocalDeviceAudioSystem mHdmiCecLocalDeviceAudioSystem; 49 private FakePowerManagerWrapper mPowerManager; 50 private TestLooper mTestLooper = new TestLooper(); 51 52 private boolean mShouldDispatchActiveSource; 53 private boolean mTvSystemAudioModeSupport; 54 private int mTryCountBeforeSucceed; 55 private HdmiDeviceInfo mDeviceInfoForTests; 56 57 private int mMsgRequestActiveSourceCount; 58 private int mMsgSetSystemAudioModeCount; 59 private int mQueryTvSystemAudioModeSupportCount; 60 private boolean mArcEnabled; 61 private boolean mIsPlaybackDevice; 62 private boolean mBroadcastActiveSource; 63 64 @Before SetUp()65 public void SetUp() { 66 mDeviceInfoForTests = HdmiDeviceInfo.hardwarePort(1001, 1234); 67 68 Context context = InstrumentationRegistry.getTargetContext(); 69 70 FakeAudioFramework audioFramework = new FakeAudioFramework(); 71 72 HdmiControlService hdmiControlService = new HdmiControlService(context, 73 Collections.emptyList(), audioFramework.getAudioManager(), 74 audioFramework.getAudioDeviceVolumeManager()) { 75 @Override 76 void sendCecCommand( 77 HdmiCecMessage command, @Nullable SendMessageCallback callback) { 78 switch (command.getOpcode()) { 79 case Constants.MESSAGE_REQUEST_ACTIVE_SOURCE: 80 mMsgRequestActiveSourceCount++; 81 if (mTryCountBeforeSucceed >= mMsgRequestActiveSourceCount 82 && callback != null) { 83 callback.onSendCompleted(SendMessageResult.NACK); 84 break; 85 } 86 if (mShouldDispatchActiveSource) { 87 mHdmiCecLocalDeviceAudioSystem.dispatchMessage( 88 HdmiCecMessageBuilder.buildActiveSource( 89 Constants.ADDR_TV, 1002)); 90 } 91 break; 92 case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE: 93 mMsgSetSystemAudioModeCount++; 94 if (mTryCountBeforeSucceed >= mMsgSetSystemAudioModeCount 95 && callback != null) { 96 callback.onSendCompleted(SendMessageResult.NACK); 97 } 98 break; 99 case Constants.MESSAGE_INITIATE_ARC: 100 break; 101 } 102 } 103 104 @Override 105 boolean isPowerStandby() { 106 return false; 107 } 108 109 @Override 110 boolean isAddressAllocated() { 111 return true; 112 } 113 114 @Override 115 protected void writeStringSystemProperty(String key, String value) { 116 } 117 118 @Override 119 int getPhysicalAddress() { 120 return 0; 121 } 122 123 @Override 124 boolean isPlaybackDevice() { 125 return mIsPlaybackDevice; 126 } 127 128 @Override 129 public void setAndBroadcastActiveSourceFromOneDeviceType( 130 int sourceAddress, int physicalAddress, String caller) { 131 mBroadcastActiveSource = true; 132 } 133 134 @Override 135 int pathToPortId(int path) { 136 return -1; 137 } 138 }; 139 140 Looper looper = mTestLooper.getLooper(); 141 hdmiControlService.setIoLooper(looper); 142 hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); 143 hdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); 144 HdmiCecController.NativeWrapper nativeWrapper = new FakeNativeWrapper(); 145 HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( 146 hdmiControlService, nativeWrapper, hdmiControlService.getAtomWriter()); 147 hdmiControlService.setCecController(hdmiCecController); 148 hdmiControlService.initService(); 149 mPowerManager = new FakePowerManagerWrapper(context); 150 hdmiControlService.setPowerManager(mPowerManager); 151 mHdmiCecLocalDeviceAudioSystem = 152 new HdmiCecLocalDeviceAudioSystem(hdmiControlService) { 153 @Override 154 void queryTvSystemAudioModeSupport( 155 TvSystemAudioModeSupportedCallback callback) { 156 mQueryTvSystemAudioModeSupportCount++; 157 if (callback != null) { 158 callback.onResult(mTvSystemAudioModeSupport); 159 } 160 } 161 162 @Override 163 HdmiDeviceInfo getDeviceInfo() { 164 return mDeviceInfoForTests; 165 } 166 167 @Override 168 void setArcStatus(boolean enabled) { 169 mArcEnabled = enabled; 170 } 171 }; 172 mHdmiCecLocalDeviceAudioSystem.init(); 173 mHdmiCecLocalDeviceAudioSystem.setDeviceInfo(mDeviceInfoForTests); 174 } 175 176 @Test testNoActiveSourceMessageReceived()177 public void testNoActiveSourceMessageReceived() { 178 resetTestVariables(); 179 mShouldDispatchActiveSource = false; 180 181 assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) 182 .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); 183 184 mHdmiCecLocalDeviceAudioSystem.addAndStartAction( 185 new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); 186 mTestLooper.dispatchAll(); 187 188 assertThat(mMsgRequestActiveSourceCount).isEqualTo(1); 189 assertThat(mMsgSetSystemAudioModeCount).isEqualTo(0); 190 assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(0); 191 assertFalse(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); 192 193 assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) 194 .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); 195 } 196 197 @Test testTvNotSupport()198 public void testTvNotSupport() { 199 resetTestVariables(); 200 mShouldDispatchActiveSource = true; 201 mTvSystemAudioModeSupport = false; 202 203 mHdmiCecLocalDeviceAudioSystem.addAndStartAction( 204 new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); 205 mTestLooper.dispatchAll(); 206 207 assertThat(mMsgRequestActiveSourceCount).isEqualTo(1); 208 assertThat(mMsgSetSystemAudioModeCount).isEqualTo(0); 209 assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); 210 assertFalse(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); 211 } 212 213 @Test 214 @Ignore("b/120845532") testTvSupport()215 public void testTvSupport() { 216 resetTestVariables(); 217 mShouldDispatchActiveSource = true; 218 mTvSystemAudioModeSupport = true; 219 220 mHdmiCecLocalDeviceAudioSystem.addAndStartAction( 221 new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); 222 mTestLooper.dispatchAll(); 223 224 assertThat(mMsgRequestActiveSourceCount).isEqualTo(1); 225 assertThat(mMsgSetSystemAudioModeCount).isEqualTo(1); 226 assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); 227 assertTrue(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); 228 229 assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) 230 .isEqualTo(1002); 231 } 232 233 @Test testKnownActiveSource()234 public void testKnownActiveSource() { 235 resetTestVariables(); 236 mTvSystemAudioModeSupport = true; 237 mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress = 1001; 238 239 mHdmiCecLocalDeviceAudioSystem.addAndStartAction( 240 new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); 241 mTestLooper.dispatchAll(); 242 243 assertThat(mMsgRequestActiveSourceCount).isEqualTo(0); 244 assertThat(mMsgSetSystemAudioModeCount).isEqualTo(1); 245 assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); 246 assertTrue(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); 247 } 248 249 @Test testRetry()250 public void testRetry() { 251 resetTestVariables(); 252 mTvSystemAudioModeSupport = true; 253 mShouldDispatchActiveSource = true; 254 mTryCountBeforeSucceed = 3; 255 assertThat(mTryCountBeforeSucceed) 256 .isAtMost(SystemAudioInitiationActionFromAvr.MAX_RETRY_COUNT); 257 assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) 258 .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); 259 260 mHdmiCecLocalDeviceAudioSystem.addAndStartAction( 261 new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); 262 mTestLooper.dispatchAll(); 263 264 assertThat(mMsgRequestActiveSourceCount).isEqualTo(4); 265 assertThat(mMsgSetSystemAudioModeCount).isEqualTo(4); 266 assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); 267 assertTrue(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()); 268 } 269 270 @Ignore("b/120845532") 271 @Test testIsPlaybackDevice_cannotReceiveActiveSource()272 public void testIsPlaybackDevice_cannotReceiveActiveSource() { 273 resetTestVariables(); 274 mIsPlaybackDevice = true; 275 assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress) 276 .isEqualTo(Constants.INVALID_PHYSICAL_ADDRESS); 277 278 mHdmiCecLocalDeviceAudioSystem.addAndStartAction( 279 new SystemAudioInitiationActionFromAvr(mHdmiCecLocalDeviceAudioSystem)); 280 mTestLooper.dispatchAll(); 281 282 assertThat(mMsgRequestActiveSourceCount).isEqualTo(1); 283 assertThat(mBroadcastActiveSource).isTrue(); 284 assertThat(mQueryTvSystemAudioModeSupportCount).isEqualTo(1); 285 assertThat(mMsgSetSystemAudioModeCount).isEqualTo(1); 286 assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isTrue(); 287 } 288 resetTestVariables()289 private void resetTestVariables() { 290 mMsgRequestActiveSourceCount = 0; 291 mMsgSetSystemAudioModeCount = 0; 292 mQueryTvSystemAudioModeSupportCount = 0; 293 mTryCountBeforeSucceed = 0; 294 mIsPlaybackDevice = false; 295 mBroadcastActiveSource = false; 296 mHdmiCecLocalDeviceAudioSystem.getActiveSource().physicalAddress = 297 Constants.INVALID_PHYSICAL_ADDRESS; 298 } 299 } 300