diff options
3 files changed, 67 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java b/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java index 46b4f48165f9..44907457f649 100644 --- a/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java +++ b/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java @@ -17,8 +17,10 @@ package com.android.server.hdmi; import android.hardware.hdmi.HdmiDeviceInfo; + import java.util.ArrayList; import java.util.Iterator; +import java.util.List; /** * Buffer storage to keep incoming messages for later processing. Used to @@ -83,6 +85,16 @@ final class DelayedMessageBuffer { return false; } + List<HdmiCecMessage> getBufferedMessagesWithOpcode(int opcode) { + List<HdmiCecMessage> messages = new ArrayList<>(); + for (HdmiCecMessage message : mBuffer) { + if (message.getOpcode() == opcode) { + messages.add(message); + } + } + return messages; + } + void processAllMessages() { // Use the copied buffer. ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<>(mBuffer); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 803f5d7afb28..978a8c0e1a45 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -205,7 +205,9 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { resetSelectRequestBuffer(); launchDeviceDiscovery(); startQueuedActions(); - if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) { + List<HdmiCecMessage> bufferedActiveSource = mDelayedMessageBuffer + .getBufferedMessagesWithOpcode(Constants.MESSAGE_ACTIVE_SOURCE); + if (bufferedActiveSource.isEmpty()) { if (hasAction(RequestActiveSourceAction.class)) { Slog.i(TAG, "RequestActiveSourceAction is in progress. Restarting."); removeAction(RequestActiveSourceAction.class); @@ -224,7 +226,31 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } } })); + } else { + addCecDeviceForBufferedActiveSource(bufferedActiveSource.get(0)); + } + } + + // Add a new CEC device with known information from the buffered <Active Source> message. This + // helps TvInputCallback#onInputAdded to be called such that the message can be processed and + // the TV to switch to the new active input. + @ServiceThreadOnly + private void addCecDeviceForBufferedActiveSource(HdmiCecMessage bufferedActiveSource) { + assertRunOnServiceThread(); + if (bufferedActiveSource == null) { + return; } + int source = bufferedActiveSource.getSource(); + int physicalAddress = HdmiUtils.twoBytesToInt(bufferedActiveSource.getParams()); + List<Integer> deviceTypes = HdmiUtils.getTypeFromAddress(source); + HdmiDeviceInfo newDevice = HdmiDeviceInfo.cecDeviceBuilder() + .setLogicalAddress(source) + .setPhysicalAddress(physicalAddress) + .setDisplayName(HdmiUtils.getDefaultDeviceName(source)) + .setDeviceType(deviceTypes.get(0)) + .setVendorId(Constants.VENDOR_ID_UNKNOWN) + .build(); + mService.getHdmiCecNetwork().addCecDevice(newDevice); } @ServiceThreadOnly diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index dca59fe0e743..128d7381dc22 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -2075,4 +2075,32 @@ public class HdmiCecLocalDeviceTvTest { // NewDeviceAction did not start and <Give OSD Name> was not sent. assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveOsdName); } + + @Test + public void onOneTouchPlay_wakeUp_addCecDevice() { + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .isEmpty(); + mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( + HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, + HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED); + mPowerManager.setInteractive(false); + mTestLooper.dispatchAll(); + + HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1, + mTvLogicalAddress); + HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, + 0x1000); + assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED); + assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(activeSource)).isEqualTo( + Constants.HANDLED); + mTestLooper.dispatchAll(); + assertThat(mPowerManager.isInteractive()).isTrue(); + + // FakePowerManagerWrapper#wakeUp() doesn't broadcast Intent.ACTION_SCREEN_ON so we have to + // manually call this method. + mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) + .hasSize(1); + } } |