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.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; 19 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.mockito.Mockito.spy; 24 25 import android.content.Context; 26 import android.content.ContextWrapper; 27 import android.hardware.hdmi.HdmiControlManager; 28 import android.hardware.hdmi.IHdmiControlCallback; 29 import android.hardware.tv.cec.V1_0.SendMessageResult; 30 import android.os.Looper; 31 import android.os.test.TestLooper; 32 import android.platform.test.annotations.Presubmit; 33 34 import androidx.test.InstrumentationRegistry; 35 import androidx.test.filters.SmallTest; 36 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 import org.junit.runners.JUnit4; 41 import org.mockito.MockitoAnnotations; 42 43 import java.util.ArrayList; 44 import java.util.Collections; 45 46 /** Tests for {@link ArcTerminationActionFromAvr} */ 47 @SmallTest 48 @Presubmit 49 @RunWith(JUnit4.class) 50 public class ArcTerminationActionFromAvrTest { 51 52 private Context mContextSpy; 53 private HdmiCecLocalDeviceAudioSystem mHdmiCecLocalDeviceAudioSystem; 54 private FakePowerManagerWrapper mPowerManager; 55 private TestCallback mCallback; 56 private ArcTerminationActionFromAvr mAction; 57 58 private FakeNativeWrapper mNativeWrapper; 59 60 private TestLooper mTestLooper = new TestLooper(); 61 private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>(); 62 63 @Before setUp()64 public void setUp() throws Exception { 65 MockitoAnnotations.initMocks(this); 66 67 mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); 68 69 FakeAudioFramework audioFramework = new FakeAudioFramework(); 70 71 HdmiControlService hdmiControlService = 72 new HdmiControlService(mContextSpy, Collections.emptyList(), 73 audioFramework.getAudioManager(), 74 audioFramework.getAudioDeviceVolumeManager()) { 75 @Override 76 boolean isPowerStandby() { 77 return false; 78 } 79 80 @Override 81 boolean isAddressAllocated() { 82 return true; 83 } 84 85 @Override 86 protected void writeStringSystemProperty(String key, String value) { 87 } 88 89 @Override 90 protected Looper getServiceLooper() { 91 return mTestLooper.getLooper(); 92 } 93 }; 94 95 Looper looper = mTestLooper.getLooper(); 96 hdmiControlService.setIoLooper(looper); 97 hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy)); 98 hdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); 99 mNativeWrapper = new FakeNativeWrapper(); 100 HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper( 101 hdmiControlService, mNativeWrapper, hdmiControlService.getAtomWriter()); 102 hdmiControlService.setCecController(hdmiCecController); 103 hdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(hdmiControlService)); 104 hdmiControlService.initService(); 105 mPowerManager = new FakePowerManagerWrapper(mContextSpy); 106 hdmiControlService.setPowerManager(mPowerManager); 107 mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(hdmiControlService) { 108 @Override 109 protected void setPreferredAddress(int addr) { 110 } 111 }; 112 mHdmiCecLocalDeviceAudioSystem.init(); 113 mCallback = new TestCallback(); 114 mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem, 115 mCallback); 116 117 mLocalDevices.add(mHdmiCecLocalDeviceAudioSystem); 118 hdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); 119 hdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); 120 mHdmiCecLocalDeviceAudioSystem.setArcStatus(true); 121 mTestLooper.dispatchAll(); 122 } 123 124 private static class TestCallback extends IHdmiControlCallback.Stub { 125 private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>(); 126 127 @Override onComplete(int result)128 public void onComplete(int result) { 129 mCallbackResult.add(result); 130 } 131 getResult()132 private int getResult() { 133 assertThat(mCallbackResult.size()).isEqualTo(1); 134 return mCallbackResult.get(0); 135 } 136 } 137 138 @Test testSendMessage_sendFailed()139 public void testSendMessage_sendFailed() { 140 mNativeWrapper.setMessageSendResult(Constants.MESSAGE_TERMINATE_ARC, 141 SendMessageResult.NACK); 142 mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction); 143 mTestLooper.dispatchAll(); 144 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 145 Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_TV); 146 147 assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc); 148 149 assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); 150 assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 151 } 152 153 @Test testReportArcTerminated_timeout()154 public void testReportArcTerminated_timeout() { 155 mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction); 156 mTestLooper.dispatchAll(); 157 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 158 Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_TV); 159 160 assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc); 161 mTestLooper.dispatchAll(); 162 163 mTestLooper.moveTimeForward(ArcTerminationActionFromAvr.TIMEOUT_MS); 164 mTestLooper.dispatchAll(); 165 166 assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); 167 assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT); 168 } 169 170 @Test testReportArcTerminated_received()171 public void testReportArcTerminated_received() { 172 mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction); 173 mTestLooper.dispatchAll(); 174 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 175 Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_TV); 176 177 assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc); 178 179 HdmiCecMessage arcTerminatedResponse = HdmiCecMessageBuilder.buildReportArcTerminated( 180 Constants.ADDR_TV, Constants.ADDR_AUDIO_SYSTEM); 181 182 mNativeWrapper.onCecMessage(arcTerminatedResponse); 183 mTestLooper.dispatchAll(); 184 185 assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); 186 assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); 187 } 188 189 @Test testReportArcTerminated_featureAbort()190 public void testReportArcTerminated_featureAbort() { 191 mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction); 192 mTestLooper.dispatchAll(); 193 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 194 Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_TV); 195 196 assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc); 197 198 HdmiCecMessage arcTerminatedResponse = HdmiCecMessageBuilder.buildFeatureAbortCommand( 199 Constants.ADDR_TV, 200 Constants.ADDR_AUDIO_SYSTEM, 201 Constants.MESSAGE_TERMINATE_ARC, 202 Constants.ABORT_REFUSED); 203 204 mNativeWrapper.onCecMessage(arcTerminatedResponse); 205 mTestLooper.dispatchAll(); 206 207 assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); 208 assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 209 } 210 } 211