Loading services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +11 −0 Original line number Diff line number Diff line Loading @@ -286,6 +286,17 @@ public class HdmiCecMessageBuilder { return HdmiCecMessage.build(src, dest, Constants.MESSAGE_TEXT_VIEW_ON); } /** * Build <Image View On> command. * * @param src source address of command * @param dest destination address of command * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildImageViewOn(int src, int dest) { return HdmiCecMessage.build(src, dest, Constants.MESSAGE_IMAGE_VIEW_ON); } /** * Build <Request Active Source> command. * Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +26 −1 Original line number Diff line number Diff line Loading @@ -1529,8 +1529,33 @@ public class HdmiControlService extends SystemService { @ServiceThreadOnly void sendCecCommand(HdmiCecMessage command) { assertRunOnServiceThread(); switch (command.getOpcode()) { case Constants.MESSAGE_ACTIVE_SOURCE: case Constants.MESSAGE_IMAGE_VIEW_ON: case Constants.MESSAGE_INACTIVE_SOURCE: case Constants.MESSAGE_ROUTING_CHANGE: case Constants.MESSAGE_SET_STREAM_PATH: case Constants.MESSAGE_TEXT_VIEW_ON: sendCecCommandWithRetries(command); break; default: sendCecCommand(command, null); } } /** * Create a {@link SendCecCommandAction} that will retry to send the CEC message in case it * fails. * @param command that has to be sent in the CEC bus. */ @ServiceThreadOnly public void sendCecCommandWithRetries(HdmiCecMessage command) { assertRunOnServiceThread(); HdmiCecLocalDevice localDevice = getAllCecLocalDevices().get(0); if (localDevice != null) { localDevice.addAndStartAction(new SendCecCommandAction(localDevice, command)); } } /** * Send <Feature Abort> command on the given CEC message if possible. Loading services/core/java/com/android/server/hdmi/SendCecCommandAction.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 android.hardware.tv.cec.V1_0.SendMessageResult; import android.util.Slog; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** * Action that sends a CEC command. If the message fails to be sent, it tries again for * RETRANSMISSION_COUNT times. */ public class SendCecCommandAction extends HdmiCecFeatureAction { private static final String TAG = "SendCecCommandAction"; private static final int RETRANSMISSION_COUNT = 2; private static final int STATE_WAIT_FOR_RESEND_COMMAND = 1; static final int SEND_COMMAND_RETRY_MS = 300; private final HdmiCecMessage mCommand; private int mRetransmissionCount = 0; private final SendMessageCallback mCallback = new SendMessageCallback(){ @Override public void onSendCompleted(int result) { if (result != SendMessageResult.SUCCESS && mRetransmissionCount++ < RETRANSMISSION_COUNT) { mState = STATE_WAIT_FOR_RESEND_COMMAND; addTimer(mState, SEND_COMMAND_RETRY_MS); } else { finish(); } } }; SendCecCommandAction(HdmiCecLocalDevice source, HdmiCecMessage command) { super(source); mCommand = command; } @Override boolean start() { Slog.d(TAG, "SendCecCommandAction started"); sendCommand(mCommand, mCallback); return true; } @Override void handleTimerEvent(int state) { if (mState != state) { Slog.w(TAG, "Timeout in invalid state:[Expected:" + mState + ", Actual:" + state + "]"); return; } if (mState == STATE_WAIT_FOR_RESEND_COMMAND) { Slog.d(TAG, "sendCecCommand failed, retry"); sendCommand(mCommand, mCallback); } } @Override boolean processCommand(HdmiCecMessage command) { return false; } } services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,11 @@ public class DeviceSelectActionFromPlaybackTest { boolean isPowerStandbyOrTransient() { return false; } @Override boolean isPowerStandby() { return false; } }; Loading services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,11 @@ public class DeviceSelectActionFromTvTest { boolean isPowerStandbyOrTransient() { return false; } @Override boolean isPowerStandby() { return false; } }; Loading Loading
services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +11 −0 Original line number Diff line number Diff line Loading @@ -286,6 +286,17 @@ public class HdmiCecMessageBuilder { return HdmiCecMessage.build(src, dest, Constants.MESSAGE_TEXT_VIEW_ON); } /** * Build <Image View On> command. * * @param src source address of command * @param dest destination address of command * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage buildImageViewOn(int src, int dest) { return HdmiCecMessage.build(src, dest, Constants.MESSAGE_IMAGE_VIEW_ON); } /** * Build <Request Active Source> command. * Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +26 −1 Original line number Diff line number Diff line Loading @@ -1529,8 +1529,33 @@ public class HdmiControlService extends SystemService { @ServiceThreadOnly void sendCecCommand(HdmiCecMessage command) { assertRunOnServiceThread(); switch (command.getOpcode()) { case Constants.MESSAGE_ACTIVE_SOURCE: case Constants.MESSAGE_IMAGE_VIEW_ON: case Constants.MESSAGE_INACTIVE_SOURCE: case Constants.MESSAGE_ROUTING_CHANGE: case Constants.MESSAGE_SET_STREAM_PATH: case Constants.MESSAGE_TEXT_VIEW_ON: sendCecCommandWithRetries(command); break; default: sendCecCommand(command, null); } } /** * Create a {@link SendCecCommandAction} that will retry to send the CEC message in case it * fails. * @param command that has to be sent in the CEC bus. */ @ServiceThreadOnly public void sendCecCommandWithRetries(HdmiCecMessage command) { assertRunOnServiceThread(); HdmiCecLocalDevice localDevice = getAllCecLocalDevices().get(0); if (localDevice != null) { localDevice.addAndStartAction(new SendCecCommandAction(localDevice, command)); } } /** * Send <Feature Abort> command on the given CEC message if possible. Loading
services/core/java/com/android/server/hdmi/SendCecCommandAction.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 android.hardware.tv.cec.V1_0.SendMessageResult; import android.util.Slog; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** * Action that sends a CEC command. If the message fails to be sent, it tries again for * RETRANSMISSION_COUNT times. */ public class SendCecCommandAction extends HdmiCecFeatureAction { private static final String TAG = "SendCecCommandAction"; private static final int RETRANSMISSION_COUNT = 2; private static final int STATE_WAIT_FOR_RESEND_COMMAND = 1; static final int SEND_COMMAND_RETRY_MS = 300; private final HdmiCecMessage mCommand; private int mRetransmissionCount = 0; private final SendMessageCallback mCallback = new SendMessageCallback(){ @Override public void onSendCompleted(int result) { if (result != SendMessageResult.SUCCESS && mRetransmissionCount++ < RETRANSMISSION_COUNT) { mState = STATE_WAIT_FOR_RESEND_COMMAND; addTimer(mState, SEND_COMMAND_RETRY_MS); } else { finish(); } } }; SendCecCommandAction(HdmiCecLocalDevice source, HdmiCecMessage command) { super(source); mCommand = command; } @Override boolean start() { Slog.d(TAG, "SendCecCommandAction started"); sendCommand(mCommand, mCallback); return true; } @Override void handleTimerEvent(int state) { if (mState != state) { Slog.w(TAG, "Timeout in invalid state:[Expected:" + mState + ", Actual:" + state + "]"); return; } if (mState == STATE_WAIT_FOR_RESEND_COMMAND) { Slog.d(TAG, "sendCecCommand failed, retry"); sendCommand(mCommand, mCallback); } } @Override boolean processCommand(HdmiCecMessage command) { return false; } }
services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,11 @@ public class DeviceSelectActionFromPlaybackTest { boolean isPowerStandbyOrTransient() { return false; } @Override boolean isPowerStandby() { return false; } }; Loading
services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java +5 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,11 @@ public class DeviceSelectActionFromTvTest { boolean isPowerStandbyOrTransient() { return false; } @Override boolean isPowerStandby() { return false; } }; Loading