Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +12 −3 Original line number Diff line number Diff line Loading @@ -191,9 +191,16 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { launchDeviceDiscovery(); startQueuedActions(); if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) { mService.sendCecCommand( HdmiCecMessageBuilder.buildRequestActiveSource( getDeviceInfo().getLogicalAddress())); addAndStartAction(new RequestActiveSourceAction(this, new IHdmiControlCallback.Stub() { @Override public void onComplete(int result) { if (result != HdmiControlManager.RESULT_SUCCESS) { mService.sendCecCommand(HdmiCecMessageBuilder.buildActiveSource( getDeviceInfo().getLogicalAddress(), getDeviceInfo().getPhysicalAddress())); } } })); } } Loading Loading @@ -1325,6 +1332,8 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { removeAction(TimerRecordingAction.class); removeAction(NewDeviceAction.class); removeAction(AbsoluteVolumeAudioStatusAction.class); // Remove pending actions. removeAction(RequestActiveSourceAction.class); // Keep SAM enabled if eARC is enabled, unless we're going to Standby. if (initiatedByCec || !mService.isEarcEnabled()){ Loading services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java 0 → 100644 +66 −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.hdmi.HdmiControlManager; import android.hardware.hdmi.IHdmiControlCallback; import android.util.Slog; /** * Feature action that sends <Request Active Source> message and waits for <Active Source>. */ public class RequestActiveSourceAction extends HdmiCecFeatureAction { private static final String TAG = "RequestActiveSourceAction"; // State to wait for the <Active Source> message. private static final int STATE_WAIT_FOR_ACTIVE_SOURCE = 1; RequestActiveSourceAction(HdmiCecLocalDevice source, IHdmiControlCallback callback) { super(source, callback); } @Override boolean start() { Slog.v(TAG, "RequestActiveSourceAction started."); sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress())); mState = STATE_WAIT_FOR_ACTIVE_SOURCE; addTimer(mState, HdmiConfig.TIMEOUT_MS); return true; } @Override boolean processCommand(HdmiCecMessage cmd) { // The action finishes successfully if the <Active Source> message is received. // {@link HdmiCecLocalDevice#onMessage} handles this message, so false is returned. if (cmd.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE) { finishWithCallback(HdmiControlManager.RESULT_SUCCESS); } return false; } @Override void handleTimerEvent(int state) { if (mState != state) { return; } if (mState == STATE_WAIT_FOR_ACTIVE_SOURCE) { finishWithCallback(HdmiControlManager.RESULT_TIMEOUT); } } } services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -1680,4 +1680,47 @@ public class HdmiCecLocalDeviceTvTest { assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); } @Test public void onAddressAllocated_startRequestActiveSourceAction_playbackActiveSource() { HdmiCecMessage requestActiveSource = HdmiCecMessageBuilder.buildRequestActiveSource(ADDR_TV); HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000); HdmiCecMessage activeSourceFromTv = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); mHdmiControlService.getHdmiCecNetwork().clearLocalDevices(); mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); mNativeWrapper.clearResultMessages(); mNativeWrapper.onCecMessage(activeSourceFromPlayback); mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSourceFromTv); } @Test public void onAddressAllocated_startRequestActiveSourceAction_noActiveSource() { HdmiCecMessage requestActiveSource = HdmiCecMessageBuilder.buildRequestActiveSource(ADDR_TV); HdmiCecMessage activeSourceFromTv = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); mHdmiControlService.getHdmiCecNetwork().clearLocalDevices(); mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); mNativeWrapper.clearResultMessages(); mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(activeSourceFromTv); } } Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +12 −3 Original line number Diff line number Diff line Loading @@ -191,9 +191,16 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { launchDeviceDiscovery(); startQueuedActions(); if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) { mService.sendCecCommand( HdmiCecMessageBuilder.buildRequestActiveSource( getDeviceInfo().getLogicalAddress())); addAndStartAction(new RequestActiveSourceAction(this, new IHdmiControlCallback.Stub() { @Override public void onComplete(int result) { if (result != HdmiControlManager.RESULT_SUCCESS) { mService.sendCecCommand(HdmiCecMessageBuilder.buildActiveSource( getDeviceInfo().getLogicalAddress(), getDeviceInfo().getPhysicalAddress())); } } })); } } Loading Loading @@ -1325,6 +1332,8 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { removeAction(TimerRecordingAction.class); removeAction(NewDeviceAction.class); removeAction(AbsoluteVolumeAudioStatusAction.class); // Remove pending actions. removeAction(RequestActiveSourceAction.class); // Keep SAM enabled if eARC is enabled, unless we're going to Standby. if (initiatedByCec || !mService.isEarcEnabled()){ Loading
services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java 0 → 100644 +66 −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.hdmi.HdmiControlManager; import android.hardware.hdmi.IHdmiControlCallback; import android.util.Slog; /** * Feature action that sends <Request Active Source> message and waits for <Active Source>. */ public class RequestActiveSourceAction extends HdmiCecFeatureAction { private static final String TAG = "RequestActiveSourceAction"; // State to wait for the <Active Source> message. private static final int STATE_WAIT_FOR_ACTIVE_SOURCE = 1; RequestActiveSourceAction(HdmiCecLocalDevice source, IHdmiControlCallback callback) { super(source, callback); } @Override boolean start() { Slog.v(TAG, "RequestActiveSourceAction started."); sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress())); mState = STATE_WAIT_FOR_ACTIVE_SOURCE; addTimer(mState, HdmiConfig.TIMEOUT_MS); return true; } @Override boolean processCommand(HdmiCecMessage cmd) { // The action finishes successfully if the <Active Source> message is received. // {@link HdmiCecLocalDevice#onMessage} handles this message, so false is returned. if (cmd.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE) { finishWithCallback(HdmiControlManager.RESULT_SUCCESS); } return false; } @Override void handleTimerEvent(int state) { if (mState != state) { return; } if (mState == STATE_WAIT_FOR_ACTIVE_SOURCE) { finishWithCallback(HdmiControlManager.RESULT_TIMEOUT); } } }
services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -1680,4 +1680,47 @@ public class HdmiCecLocalDeviceTvTest { assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); } @Test public void onAddressAllocated_startRequestActiveSourceAction_playbackActiveSource() { HdmiCecMessage requestActiveSource = HdmiCecMessageBuilder.buildRequestActiveSource(ADDR_TV); HdmiCecMessage activeSourceFromPlayback = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000); HdmiCecMessage activeSourceFromTv = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); mHdmiControlService.getHdmiCecNetwork().clearLocalDevices(); mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); mNativeWrapper.clearResultMessages(); mNativeWrapper.onCecMessage(activeSourceFromPlayback); mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSourceFromTv); } @Test public void onAddressAllocated_startRequestActiveSourceAction_noActiveSource() { HdmiCecMessage requestActiveSource = HdmiCecMessageBuilder.buildRequestActiveSource(ADDR_TV); HdmiCecMessage activeSourceFromTv = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000); mHdmiControlService.getHdmiCecNetwork().clearLocalDevices(); mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource); mNativeWrapper.clearResultMessages(); mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); mTestLooper.dispatchAll(); assertThat(mNativeWrapper.getResultMessages()).contains(activeSourceFromTv); } }