diff options
3 files changed, 35 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java index e827866368fe..10c01864457e 100755 --- a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java +++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java @@ -140,7 +140,13 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction { wrapUpAndFinish(); return; } - + // Check if the action was finished before the callback was called. + // See {@link HdmiCecFeatureAction#finish}. + if (mState == STATE_NONE) { + Slog.v(TAG, "Action was already finished before the callback was called."); + wrapUpAndFinish(); + return; + } Slog.v(TAG, "Device detected: " + ackedAddress); allocateDevices(ackedAddress); if (mDelayPeriod > 0) { @@ -453,7 +459,6 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction { wrapUpAndFinish(); return; } - // If finished current stage, move on to next stage. if (mProcessedDeviceCount == mDevices.size()) { mProcessedDeviceCount = 0; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 9087354dee40..a79fb88ea8b6 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -160,6 +160,9 @@ final class HdmiCecController { // This variable is used for testing, in order to delay the logical address allocation. private long mLogicalAddressAllocationDelay = 0; + // This variable is used for testing, in order to delay polling devices. + private long mPollDevicesDelay = 0; + // Private constructor. Use HdmiCecController.create(). private HdmiCecController( HdmiControlService service, NativeWrapper nativeWrapper, HdmiCecAtomWriter atomWriter) { @@ -463,6 +466,14 @@ final class HdmiCecController { } /** + * This method is used for testing, in order to delay polling devices. + */ + @VisibleForTesting + void setPollDevicesDelay(long delay) { + mPollDevicesDelay = delay; + } + + /** * Returns true if the language code is well-formed. */ @VisibleForTesting static boolean isLanguage(String language) { @@ -523,7 +534,10 @@ final class HdmiCecController { // Extract polling candidates. No need to poll against local devices. List<Integer> pollingCandidates = pickPollCandidates(pickStrategy); ArrayList<Integer> allocated = new ArrayList<>(); - runDevicePolling(sourceAddress, pollingCandidates, retryCount, callback, allocated); + mControlHandler.postDelayed( + () -> runDevicePolling( + sourceAddress, pollingCandidates, retryCount, callback, allocated), + mPollDevicesDelay); } private List<Integer> pickPollCandidates(int pickStrategy) { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java index 543fa5727f19..62073497b735 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java @@ -1775,6 +1775,11 @@ public class HdmiCecLocalDevicePlaybackTest { @Test public void wakeUp_hotPlugIn_invokesDeviceDiscoveryOnce() { + // There might be a leftover HotplugDetectionAction that can interfere with the test. + mHdmiCecLocalDevicePlayback.removeAction(HotplugDetectionAction.class); + + long pollingDelay = TimeUnit.SECONDS.toMillis(60); + mHdmiCecController.setPollDevicesDelay(pollingDelay); mNativeWrapper.setPollAddressResponse(Constants.ADDR_PLAYBACK_2, SendMessageResult.SUCCESS); mHdmiControlService.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON); mTestLooper.dispatchAll(); @@ -1783,6 +1788,14 @@ public class HdmiCecLocalDevicePlaybackTest { mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDevicePlayback.getActions(DeviceDiscoveryAction.class)).hasSize(1); + mTestLooper.moveTimeForward(pollingDelay); + mTestLooper.dispatchAll(); + + HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress( + Constants.ADDR_PLAYBACK_1, + Constants.ADDR_PLAYBACK_2); + assertThat(mNativeWrapper.getResultMessages().stream() + .filter(message -> message.equals(givePhysicalAddress)).count()).isEqualTo(1); } @Test |