diff options
| author | 2020-01-17 11:13:53 +0000 | |
|---|---|---|
| committer | 2020-01-17 11:13:53 +0000 | |
| commit | c467ff4f518c16c727103896d9d64b6e401439a9 (patch) | |
| tree | 975e29c4f1fb39244bf58753a446c6b91b392528 | |
| parent | 28d29b36a5d53954516bcb0ba7574983f657d831 (diff) | |
| parent | 04848a3e17b52ebfd3ca99bed49a295fe801fa50 (diff) | |
Merge "Initialize HDMI PowerStatus to standby"
| -rw-r--r-- | services/core/java/com/android/server/hdmi/HdmiControlService.java | 50 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java | 67 |
2 files changed, 104 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 1794df3b602e..7c2ec78c1cbc 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -491,7 +491,7 @@ public class HdmiControlService extends SystemService { mIoThread.start(); mIoLooper = mIoThread.getLooper(); } - mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON; + mPowerStatus = getInitialPowerStatus(); mProhibitMode = false; mHdmiControlEnabled = readBooleanSetting(Global.HDMI_CONTROL_ENABLED, true); mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true); @@ -538,6 +538,28 @@ public class HdmiControlService extends SystemService { mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, ENABLED); } + private void bootCompleted() { + // on boot, if device is interactive, set HDMI CEC state as powered on as well + if (mPowerManager.isInteractive() && isPowerStandbyOrTransient()) { + onWakeUp(); + } + } + + /** + * Returns the initial power status used when the HdmiControlService starts. + */ + @VisibleForTesting + int getInitialPowerStatus() { + // The initial power status is POWER_STATUS_TRANSIENT_TO_STANDBY. + // Once boot completes the service transitions to POWER_STATUS_ON if the device is + // interactive. + // Quiescent boot is a special boot mode, in which the screen stays off during boot + // and the device goes to sleep after boot has finished. + // We don't transition to POWER_STATUS_ON initially, as we might be booting in quiescent + // mode, during which we don't want to appear powered on to avoid being made active source. + return HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY; + } + @VisibleForTesting void setCecController(HdmiCecController cecController) { mCecController = cecController; @@ -553,7 +575,9 @@ public class HdmiControlService extends SystemService { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { mTvInputManager = (TvInputManager) getContext().getSystemService( Context.TV_INPUT_SERVICE); - mPowerManager = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); + mPowerManager = getContext().getSystemService(PowerManager.class); + } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { + runOnServiceThread(this::bootCompleted); } } @@ -579,9 +603,7 @@ public class HdmiControlService extends SystemService { * Called when the initialization of local devices is complete. */ private void onInitializeCecComplete(int initiatedBy) { - if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) { - mPowerStatus = HdmiControlManager.POWER_STATUS_ON; - } + updatePowerStatusOnInitializeCecComplete(); mWakeUpMessageReceived = false; if (isTvDeviceEnabled()) { @@ -606,6 +628,17 @@ public class HdmiControlService extends SystemService { } } + /** + * Updates the power status once the initialization of local devices is complete. + */ + private void updatePowerStatusOnInitializeCecComplete() { + if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) { + mPowerStatus = HdmiControlManager.POWER_STATUS_ON; + } else if (mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY) { + mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY; + } + } + private void registerContentObserver() { ContentResolver resolver = getContext().getContentResolver(); String[] settings = new String[] { @@ -2667,6 +2700,13 @@ public class HdmiControlService extends SystemService { } @ServiceThreadOnly + @VisibleForTesting + void setPowerStatus(int powerStatus) { + assertRunOnServiceThread(); + mPowerStatus = powerStatus; + } + + @ServiceThreadOnly boolean isPowerOnOrTransient() { assertRunOnServiceThread(); return mPowerStatus == HdmiControlManager.POWER_STATUS_ON diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java index 1f660742122d..9e98427db709 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM; import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK; +import static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; import static com.google.common.truth.Truth.assertThat; @@ -25,8 +26,17 @@ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.ContextWrapper; +import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPortInfo; +import android.os.IPowerManager; import android.os.Looper; +import android.os.PowerManager; +import android.os.RemoteException; import android.os.test.TestLooper; import androidx.test.InstrumentationRegistry; @@ -36,6 +46,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.util.ArrayList; @@ -98,6 +110,7 @@ public class HdmiControlServiceTest { } private static final String TAG = "HdmiControlServiceTest"; + private Context mContextSpy; private HdmiControlService mHdmiControlService; private HdmiCecController mHdmiCecController; private HdmiCecLocalDeviceMyDevice mMyAudioSystemDevice; @@ -109,15 +122,24 @@ public class HdmiControlServiceTest { private boolean mStandbyMessageReceived; private HdmiPortInfo[] mHdmiPortInfo; + @Mock private IPowerManager mIPowerManagerMock; + @Before - public void SetUp() { - mHdmiControlService = - new HdmiControlService(InstrumentationRegistry.getTargetContext()) { - @Override - boolean isStandbyMessageReceived() { - return mStandbyMessageReceived; - } - }; + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); + + PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock, null); + when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager); + when(mIPowerManagerMock.isInteractive()).thenReturn(true); + + mHdmiControlService = new HdmiControlService(mContextSpy) { + @Override + boolean isStandbyMessageReceived() { + return mStandbyMessageReceived; + } + }; mMyLooper = mTestLooper.getLooper(); mMyAudioSystemDevice = @@ -198,4 +220,33 @@ public class HdmiControlServiceTest { mHdmiControlService.initPortInfo(); assertThat(mHdmiControlService.pathToPortId(0x1000)).isEqualTo(Constants.INVALID_PORT_ID); } + + @Test + public void initialPowerStatus_normalBoot_isTransientToStandby() { + assertThat(mHdmiControlService.getInitialPowerStatus()).isEqualTo( + HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY); + } + + @Test + public void initialPowerStatus_quiescentBoot_isTransientToStandby() throws RemoteException { + when(mIPowerManagerMock.isInteractive()).thenReturn(false); + assertThat(mHdmiControlService.getInitialPowerStatus()).isEqualTo( + HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY); + } + + @Test + public void powerStatusAfterBootComplete_normalBoot_isOn() { + mHdmiControlService.setPowerStatus(HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON); + mHdmiControlService.onBootPhase(PHASE_BOOT_COMPLETED); + assertThat(mHdmiControlService.getPowerStatus()).isEqualTo( + HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON); + } + + @Test + public void powerStatusAfterBootComplete_quiescentBoot_isStandby() throws RemoteException { + when(mIPowerManagerMock.isInteractive()).thenReturn(false); + mHdmiControlService.onBootPhase(PHASE_BOOT_COMPLETED); + assertThat(mHdmiControlService.getPowerStatus()).isEqualTo( + HdmiControlManager.POWER_STATUS_STANDBY); + } } |