Loading services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +27 −1 Original line number Diff line number Diff line Loading @@ -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()) { addAndStartAction(new RequestActiveSourceAction(this, new IHdmiControlCallback.Stub() { @Override public void onComplete(int result) { Loading @@ -220,7 +222,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 Loading services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE; import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -1907,4 +1908,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); } } Loading
services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +27 −1 Original line number Diff line number Diff line Loading @@ -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()) { addAndStartAction(new RequestActiveSourceAction(this, new IHdmiControlCallback.Stub() { @Override public void onComplete(int result) { Loading @@ -220,7 +222,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 Loading
services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE; import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -1907,4 +1908,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); } }