From 807dfb306788593f7ebd6f07c268c7b6310275ba Mon Sep 17 00:00:00 2001 From: Yan Han Date: Mon, 22 Mar 2021 10:23:52 +0100 Subject: [PATCH] Fix and move old One Touch Play tests Moves the One Touch Play tests in HdmiControlServiceBinderApiTest to OneTouchPlayActionTest. This fixes tests failures on ADT-3, which were caused by the test setup responding with the message on same callstack as the message, causing it to be processed before OneTouchPlayAction updated its state. Bug: 182910754 Test: atest com.android.server.hdmi.OneTouchPlayActionTest Change-Id: I11e8e2a5259739325d1dd9aae92113e85ecad47a --- .../hdmi/HdmiControlServiceBinderAPITest.java | 248 ------------------ .../server/hdmi/OneTouchPlayActionTest.java | 117 ++++++++- 2 files changed, 107 insertions(+), 258 deletions(-) delete mode 100644 services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java deleted file mode 100644 index 70718f7654128..0000000000000 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.server.hdmi; - -import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; - -import static com.google.common.truth.Truth.assertThat; - -import static junit.framework.Assert.assertEquals; - -import android.content.Context; -import android.hardware.hdmi.HdmiControlManager; -import android.hardware.hdmi.HdmiPortInfo; -import android.hardware.hdmi.IHdmiControlCallback; -import android.os.Looper; -import android.os.test.TestLooper; -import android.provider.Settings; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Tests for {@link HdmiControlServiceBinderAPITest} class. - */ -@SmallTest -@RunWith(JUnit4.class) -public class HdmiControlServiceBinderAPITest { - - private Context mContext; - - private class HdmiCecLocalDeviceMyDevice extends HdmiCecLocalDevice { - - private boolean mCanGoToStandby; - private boolean mIsStandby; - private boolean mIsDisabled; - - protected HdmiCecLocalDeviceMyDevice(HdmiControlService service, int deviceType) { - super(service, deviceType); - } - - @Override - protected void onAddressAllocated(int logicalAddress, int reason) { - } - - @Override - protected int getPreferredAddress() { - return 0; - } - - @Override - protected void setPreferredAddress(int addr) { - } - - @Override - protected boolean canGoToStandby() { - return mCanGoToStandby; - } - - @Override - protected void disableDevice( - boolean initiatedByCec, final PendingActionClearedCallback originalCallback) { - mIsDisabled = true; - originalCallback.onCleared(this); - } - - @Override - protected void onStandby(boolean initiatedByCec, int standbyAction) { - mIsStandby = true; - } - - protected boolean isStandby() { - return mIsStandby; - } - - protected boolean isDisabled() { - return mIsDisabled; - } - - protected void setCanGoToStandby(boolean canGoToStandby) { - mCanGoToStandby = canGoToStandby; - } - - @Override - protected int getRcProfile() { - return 0; - } - - @Override - protected List getRcFeatures() { - return Collections.emptyList(); - } - - @Override - protected List getDeviceFeatures() { - return Collections.emptyList(); - } - } - - private static final String TAG = "HdmiControlServiceBinderAPITest"; - private HdmiControlService mHdmiControlService; - private HdmiCecController mHdmiCecController; - private HdmiCecLocalDevicePlayback mPlaybackDevice; - private FakeNativeWrapper mNativeWrapper; - private Looper mMyLooper; - private TestLooper mTestLooper = new TestLooper(); - private ArrayList mLocalDevices = new ArrayList<>(); - private HdmiPortInfo[] mHdmiPortInfo; - private int mResult; - private int mPowerStatus; - - @Before - public void SetUp() { - mContext = InstrumentationRegistry.getTargetContext(); - // Some tests expect no logical addresses being allocated at the beginning of the test. - setHdmiControlEnabled(false); - - HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContext); - - mHdmiControlService = - new HdmiControlService(mContext) { - @Override - void sendCecCommand(HdmiCecMessage command) { - switch (command.getOpcode()) { - case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS: - HdmiCecMessage message = - HdmiCecMessageBuilder.buildReportPowerStatus( - Constants.ADDR_TV, - Constants.ADDR_PLAYBACK_1, - HdmiControlManager.POWER_STATUS_ON); - handleCecCommand(message); - break; - default: - return; - } - } - - @Override - boolean isPowerStandby() { - return mPowerStatus == HdmiControlManager.POWER_STATUS_STANDBY; - } - - @Override - protected HdmiCecConfig getHdmiCecConfig() { - return hdmiCecConfig; - } - }; - mMyLooper = mTestLooper.getLooper(); - - mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlService) { - @Override - protected void wakeUpIfActiveSource() {} - - @Override - protected void setPreferredAddress(int addr) {} - - @Override - protected int getPreferredAddress() { - return Constants.ADDR_PLAYBACK_1; - } - }; - mPlaybackDevice.init(); - - mHdmiControlService.setIoLooper(mMyLooper); - - mNativeWrapper = new FakeNativeWrapper(); - mHdmiCecController = HdmiCecController.createWithNativeWrapper( - mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); - mHdmiControlService.setCecController(mHdmiCecController); - mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService)); - mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService)); - - mLocalDevices.add(mPlaybackDevice); - mHdmiPortInfo = new HdmiPortInfo[1]; - mHdmiPortInfo[0] = - new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false); - mNativeWrapper.setPortInfo(mHdmiPortInfo); - mHdmiControlService.initService(); - mResult = -1; - mPowerStatus = HdmiControlManager.POWER_STATUS_ON; - - mTestLooper.dispatchAll(); - } - - @Test - public void oneTouchPlay_addressNotAllocated() { - assertThat(mHdmiControlService.isAddressAllocated()).isFalse(); - mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() { - @Override - public void onComplete(int result) { - mResult = result; - } - }); - assertEquals(mResult, -1); - assertThat(mPlaybackDevice.isActiveSource()).isFalse(); - - setHdmiControlEnabled(true); - mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); - mTestLooper.dispatchAll(); - assertThat(mHdmiControlService.isAddressAllocated()).isTrue(); - assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS); - assertThat(mPlaybackDevice.isActiveSource()).isTrue(); - } - - @Test - public void oneTouchPlay_addressAllocated() { - setHdmiControlEnabled(true); - - mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); - mTestLooper.dispatchAll(); - assertThat(mHdmiControlService.isAddressAllocated()).isTrue(); - mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() { - @Override - public void onComplete(int result) { - mResult = result; - } - }); - assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS); - assertThat(mPlaybackDevice.isActiveSource()).isTrue(); - } - - private void setHdmiControlEnabled(boolean enabled) { - int value = enabled ? 1 : 0; - Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.HDMI_CONTROL_ENABLED, - value); - } -} diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java index c61635cbd4b61..d74bff2837cec 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java @@ -37,13 +37,13 @@ import android.os.IThermalService; import android.os.Looper; import android.os.PowerManager; import android.os.test.TestLooper; +import android.provider.Settings; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import com.android.server.hdmi.HdmiCecFeatureAction.ActionTimer; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -79,12 +79,18 @@ public class OneTouchPlayActionTest { @Mock private IThermalService mIThermalServiceMock; - @Before - public void setUp() throws Exception { + /** + * Manually called before tests, because some tests require HDMI control to be disabled. + * @param hdmiControlEnabled whether to enable the global setting hdmi_control. + * @throws Exception + */ + public void setUp(boolean hdmiControlEnabled) throws Exception { MockitoAnnotations.initMocks(this); mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); + setHdmiControlEnabled(hdmiControlEnabled); + PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock, mIThermalServiceMock, new Handler(mTestLooper.getLooper())); when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager); @@ -146,7 +152,9 @@ public class OneTouchPlayActionTest { } @Test - public void succeedWithUnknownTvDevice() { + public void succeedWithUnknownTvDevice() throws Exception { + setUp(true); + HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); playbackDevice.init(); @@ -185,7 +193,9 @@ public class OneTouchPlayActionTest { } @Test - public void succeedAfterGettingPowerStatusOn_Cec14b() { + public void succeedAfterGettingPowerStatusOn_Cec14b() throws Exception { + setUp(true); + mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); @@ -225,7 +235,9 @@ public class OneTouchPlayActionTest { } @Test - public void succeedAfterGettingTransientPowerStatus_Cec14b() { + public void succeedAfterGettingTransientPowerStatus_Cec14b() throws Exception { + setUp(true); + mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); @@ -275,7 +287,9 @@ public class OneTouchPlayActionTest { } @Test - public void timeOut_Cec14b() { + public void timeOut_Cec14b() throws Exception { + setUp(true); + mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); @@ -316,7 +330,9 @@ public class OneTouchPlayActionTest { } @Test - public void succeedIfPowerStatusOn_Cec20() { + public void succeedIfPowerStatusOn_Cec20() throws Exception { + setUp(true); + mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); @@ -348,7 +364,9 @@ public class OneTouchPlayActionTest { } @Test - public void succeedIfPowerStatusUnknown_Cec20() { + public void succeedIfPowerStatusUnknown_Cec20() throws Exception { + setUp(true); + mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); @@ -390,7 +408,9 @@ public class OneTouchPlayActionTest { } @Test - public void succeedIfPowerStatusStandby_Cec20() { + public void succeedIfPowerStatusStandby_Cec20() throws Exception { + setUp(true); + mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV); HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( mHdmiControlService); @@ -431,6 +451,73 @@ public class OneTouchPlayActionTest { assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } + @Test + public void succeedWithAddressNotAllocated_Cec14b() throws Exception { + setUp(false); + + assertThat(mHdmiControlService.isAddressAllocated()).isFalse(); + + HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( + mHdmiControlService); + playbackDevice.init(); + mLocalDevices.add(playbackDevice); + + TestCallback callback = new TestCallback(); + + mHdmiControlService.oneTouchPlay(callback); + mTestLooper.dispatchAll(); + + assertThat(callback.hasResult()).isFalse(); + assertThat(playbackDevice.isActiveSource()).isFalse(); + + setHdmiControlEnabled(true); + mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + + mTestLooper.dispatchAll(); + + HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus( + Constants.ADDR_TV, + playbackDevice.mAddress, + HdmiControlManager.POWER_STATUS_ON + ); + mNativeWrapper.onCecMessage(reportPowerStatusMessage); + + mTestLooper.dispatchAll(); + + assertThat(mHdmiControlService.isAddressAllocated()).isTrue(); + assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); + assertThat(playbackDevice.isActiveSource()).isTrue(); + } + + @Test + public void succeedWithAddressAllocated_Cec14b() throws Exception { + setUp(true); + + HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback( + mHdmiControlService); + playbackDevice.init(); + mLocalDevices.add(playbackDevice); + + mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlService.isAddressAllocated()).isTrue(); + + TestCallback callback = new TestCallback(); + mHdmiControlService.oneTouchPlay(callback); + + HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus( + Constants.ADDR_TV, + playbackDevice.mAddress, + HdmiControlManager.POWER_STATUS_ON + ); + mNativeWrapper.onCecMessage(reportPowerStatusMessage); + + mTestLooper.dispatchAll(); + + assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); + assertThat(playbackDevice.isActiveSource()).isTrue(); + } + private static class TestActionTimer implements ActionTimer { private int mState; @@ -456,9 +543,19 @@ public class OneTouchPlayActionTest { mCallbackResult.add(result); } + private boolean hasResult() { + return mCallbackResult.size() != 0; + } + private int getResult() { assertThat(mCallbackResult.size()).isEqualTo(1); return mCallbackResult.get(0); } } + + private void setHdmiControlEnabled(boolean enabled) { + int value = enabled ? 1 : 0; + Settings.Global.putInt(mContextSpy.getContentResolver(), + Settings.Global.HDMI_CONTROL_ENABLED, value); + } }