Merge "[CEC] Always send <Set Stream Path> after Routing Changes"
This commit is contained in:
committed by
Android (Google) Code Review
commit
7f093e1c83
@@ -88,7 +88,7 @@ final class ActiveSourceHandler {
|
||||
tv.updateActiveSource(current, "ActiveSourceHandler");
|
||||
invokeCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
} else {
|
||||
tv.startRoutingControl(newActive.physicalAddress, current.physicalAddress, true,
|
||||
tv.startRoutingControl(newActive.physicalAddress, current.physicalAddress,
|
||||
mCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,12 +370,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
return;
|
||||
}
|
||||
int newPath = mService.portIdToPath(portId);
|
||||
startRoutingControl(oldPath, newPath, true, callback);
|
||||
startRoutingControl(oldPath, newPath, callback);
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
void startRoutingControl(int oldPath, int newPath, boolean queryDevicePowerStatus,
|
||||
IHdmiControlCallback callback) {
|
||||
void startRoutingControl(int oldPath, int newPath, IHdmiControlCallback callback) {
|
||||
assertRunOnServiceThread();
|
||||
if (oldPath == newPath) {
|
||||
return;
|
||||
@@ -385,7 +384,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
mService.sendCecCommand(routingChange);
|
||||
removeAction(RoutingControlAction.class);
|
||||
addAndStartAction(
|
||||
new RoutingControlAction(this, newPath, queryDevicePowerStatus, callback));
|
||||
new RoutingControlAction(this, newPath, callback));
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@@ -554,7 +553,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
if (isTailOfActivePath(path, getActivePath())) {
|
||||
int newPath = mService.portIdToPath(getActivePortId());
|
||||
setActivePath(newPath);
|
||||
startRoutingControl(getActivePath(), newPath, false, null);
|
||||
startRoutingControl(getActivePath(), newPath, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -598,7 +597,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
getActiveSource().invalidate();
|
||||
removeAction(RoutingControlAction.class);
|
||||
int newPath = HdmiUtils.twoBytesToInt(params, 2);
|
||||
addAndStartAction(new RoutingControlAction(this, newPath, true, null));
|
||||
addAndStartAction(new RoutingControlAction(this, newPath, null));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1140,7 +1139,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
// Seq #23
|
||||
if (isTailOfActivePath(path, getActivePath())) {
|
||||
int newPath = mService.portIdToPath(getActivePortId());
|
||||
startRoutingControl(getActivePath(), newPath, true, null);
|
||||
startRoutingControl(getActivePath(), newPath, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1158,7 +1157,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
if (!routingForBootup && !isProhibitMode()) {
|
||||
int newPath = mService.portIdToPath(getActivePortId());
|
||||
setActivePath(newPath);
|
||||
startRoutingControl(getActivePath(), newPath, routingForBootup, null);
|
||||
startRoutingControl(getActivePath(), newPath, null);
|
||||
}
|
||||
} else {
|
||||
int activePath = mService.getPhysicalAddress();
|
||||
|
||||
@@ -18,12 +18,11 @@ package com.android.server.hdmi;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Feature action for routing control. Exchanges routing-related commands with other devices
|
||||
@@ -43,23 +42,12 @@ final class RoutingControlAction extends HdmiCecFeatureAction {
|
||||
|
||||
// State in which we wait for <Routing Information> to arrive. If timed out, we use the
|
||||
// latest routing path to set the new active source.
|
||||
private static final int STATE_WAIT_FOR_ROUTING_INFORMATION = 1;
|
||||
|
||||
// State in which we wait for <Report Power Status> in response to <Give Device Power Status>
|
||||
// we have sent. If the response tells us the device power is on, we send <Set Stream Path>
|
||||
// to make it the active source. Otherwise we do not send <Set Stream Path>, and possibly
|
||||
// just show the blank screen.
|
||||
private static final int STATE_WAIT_FOR_REPORT_POWER_STATUS = 2;
|
||||
@VisibleForTesting
|
||||
static final int STATE_WAIT_FOR_ROUTING_INFORMATION = 1;
|
||||
|
||||
// Time out in millseconds used for <Routing Information>
|
||||
private static final int TIMEOUT_ROUTING_INFORMATION_MS = 1000;
|
||||
|
||||
// Time out in milliseconds used for <Report Power Status>
|
||||
private static final int TIMEOUT_REPORT_POWER_STATUS_MS = 1000;
|
||||
|
||||
// true if <Give Power Status> should be sent once the new active routing path is determined.
|
||||
private final boolean mQueryDevicePowerStatus;
|
||||
|
||||
// If set to true, call {@link HdmiControlService#invokeInputChangeListener()} when
|
||||
// the routing control/active source change happens. The listener should be called if
|
||||
// the events are triggered by external events such as manual switch port change or incoming
|
||||
@@ -71,12 +59,10 @@ final class RoutingControlAction extends HdmiCecFeatureAction {
|
||||
// The latest routing path. Updated by each <Routing Information> from CEC switches.
|
||||
private int mCurrentRoutingPath;
|
||||
|
||||
RoutingControlAction(HdmiCecLocalDevice localDevice, int path, boolean queryDevicePowerStatus,
|
||||
IHdmiControlCallback callback) {
|
||||
RoutingControlAction(HdmiCecLocalDevice localDevice, int path, IHdmiControlCallback callback) {
|
||||
super(localDevice);
|
||||
mCallback = callback;
|
||||
mCurrentRoutingPath = path;
|
||||
mQueryDevicePowerStatus = queryDevicePowerStatus;
|
||||
// Callback is non-null when routing control action is brought up by binder API. Use
|
||||
// this as an indicator for the input change notification. These API calls will get
|
||||
// the result through this callback, not through notification. Any other events that
|
||||
@@ -109,39 +95,16 @@ final class RoutingControlAction extends HdmiCecFeatureAction {
|
||||
removeActionExcept(RoutingControlAction.class, this);
|
||||
addTimer(mState, TIMEOUT_ROUTING_INFORMATION_MS);
|
||||
return true;
|
||||
} else if (mState == STATE_WAIT_FOR_REPORT_POWER_STATUS
|
||||
&& opcode == Constants.MESSAGE_REPORT_POWER_STATUS) {
|
||||
handleReportPowerStatus(cmd.getParams()[0]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleReportPowerStatus(int devicePowerStatus) {
|
||||
if (isPowerOnOrTransient(getTvPowerStatus())) {
|
||||
updateActiveInput();
|
||||
if (isPowerOnOrTransient(devicePowerStatus)) {
|
||||
sendSetStreamPath();
|
||||
}
|
||||
}
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
private void updateActiveInput() {
|
||||
HdmiCecLocalDeviceTv tv = tv();
|
||||
tv.setPrevPortId(tv.getActivePortId());
|
||||
tv.updateActiveInput(mCurrentRoutingPath, mNotifyInputChange);
|
||||
}
|
||||
|
||||
private int getTvPowerStatus() {
|
||||
return tv().getPowerStatus();
|
||||
}
|
||||
|
||||
private static boolean isPowerOnOrTransient(int status) {
|
||||
return status == HdmiControlManager.POWER_STATUS_ON
|
||||
|| status == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
|
||||
}
|
||||
|
||||
private void sendSetStreamPath() {
|
||||
sendCommand(HdmiCecMessageBuilder.buildSetStreamPath(getSourceAddress(),
|
||||
mCurrentRoutingPath));
|
||||
@@ -160,46 +123,13 @@ final class RoutingControlAction extends HdmiCecFeatureAction {
|
||||
}
|
||||
switch (timeoutState) {
|
||||
case STATE_WAIT_FOR_ROUTING_INFORMATION:
|
||||
HdmiDeviceInfo device =
|
||||
localDevice().mService.getHdmiCecNetwork().getDeviceInfoByPath(
|
||||
mCurrentRoutingPath);
|
||||
if (device != null && mQueryDevicePowerStatus) {
|
||||
int deviceLogicalAddress = device.getLogicalAddress();
|
||||
queryDevicePowerStatus(deviceLogicalAddress, new SendMessageCallback() {
|
||||
@Override
|
||||
public void onSendCompleted(int error) {
|
||||
handlDevicePowerStatusAckResult(
|
||||
error == HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateActiveInput();
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
return;
|
||||
case STATE_WAIT_FOR_REPORT_POWER_STATUS:
|
||||
if (isPowerOnOrTransient(getTvPowerStatus())) {
|
||||
updateActiveInput();
|
||||
sendSetStreamPath();
|
||||
}
|
||||
updateActiveInput();
|
||||
sendSetStreamPath();
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void queryDevicePowerStatus(int address, SendMessageCallback callback) {
|
||||
sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(), address),
|
||||
callback);
|
||||
}
|
||||
|
||||
private void handlDevicePowerStatusAckResult(boolean acked) {
|
||||
if (acked) {
|
||||
mState = STATE_WAIT_FOR_REPORT_POWER_STATUS;
|
||||
addTimer(mState, TIMEOUT_REPORT_POWER_STATUS_MS);
|
||||
} else {
|
||||
updateActiveInput();
|
||||
sendSetStreamPath();
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
default:
|
||||
Slog.e("CEC", "Invalid timeoutState (" + timeoutState + ").");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
|
||||
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
|
||||
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
|
||||
import static com.android.server.hdmi.Constants.ADDR_TUNER_1;
|
||||
import static com.android.server.hdmi.Constants.ADDR_TV;
|
||||
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
|
||||
import static com.android.server.hdmi.Constants.MESSAGE_ACTIVE_SOURCE;
|
||||
import static com.android.server.hdmi.Constants.MESSAGE_ROUTING_INFORMATION;
|
||||
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
|
||||
import static com.android.server.hdmi.RoutingControlAction.STATE_WAIT_FOR_ROUTING_INFORMATION;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.HdmiPortInfo;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.os.Handler;
|
||||
import android.os.IPowerManager;
|
||||
import android.os.IThermalService;
|
||||
import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.test.TestLooper;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.hdmi.HdmiCecFeatureAction.ActionTimer;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4.class)
|
||||
public class RoutingControlActionTest {
|
||||
/*
|
||||
* Example connection diagram used in tests. Double-lined paths indicate the currently active
|
||||
* routes.
|
||||
*
|
||||
*
|
||||
* +-----------+
|
||||
* | TV |
|
||||
* | 0.0.0.0 |
|
||||
* +---+-----+-+
|
||||
* | |
|
||||
* <----------+ 1) AVR -> Switch
|
||||
* +----------+ | | +-----------+
|
||||
* | AVR +---------+ +--+ Switch |
|
||||
* | 1.0.0.0 | | 2.0.0.0 |
|
||||
* +--+---++--+ +--++-----+-+ <-------+ 2) Recorder -> Blu-ray
|
||||
* | || || |
|
||||
* | || || +--------+
|
||||
* +-----------+ | || +----------+ +----++----+ |
|
||||
* | XBox +--+ ++--+ Tuner | | Blueray | +-----+----+
|
||||
* | 1.1.0.0 | | 1.2.0.0 | | 2.1.0.0 | | Recorder |
|
||||
* +-----------+ +----++----+ +----------+ | 2.2.0.0 |
|
||||
* || +----------+
|
||||
* ||
|
||||
* +----++----+
|
||||
* | Player |
|
||||
* | 1.2.1.0 |
|
||||
* +----------+
|
||||
*
|
||||
*/
|
||||
|
||||
private static final int PHYSICAL_ADDRESS_TV = 0x0000;
|
||||
private static final int PHYSICAL_ADDRESS_AVR = 0x1000;
|
||||
private static final int PHYSICAL_ADDRESS_SWITCH = 0x2000;
|
||||
private static final int PHYSICAL_ADDRESS_TUNER = 0x1200;
|
||||
private static final int PHYSICAL_ADDRESS_PLAYER = 0x1210;
|
||||
private static final int PHYSICAL_ADDRESS_BLUERAY = 0x2100;
|
||||
private static final int PHYSICAL_ADDRESS_RECORDER = 0x2200;
|
||||
private static final int PORT_1 = 1;
|
||||
private static final int PORT_2 = 2;
|
||||
private static final int VENDOR_ID_AVR = 0x11233;
|
||||
|
||||
private static final byte[] TUNER_PARAM =
|
||||
new byte[] {(PHYSICAL_ADDRESS_TUNER >> 8) & 0xFF, PHYSICAL_ADDRESS_TUNER & 0xFF};
|
||||
private static final byte[] PLAYER_PARAM =
|
||||
new byte[] {(PHYSICAL_ADDRESS_PLAYER >> 8) & 0xFF, PHYSICAL_ADDRESS_PLAYER & 0xFF};
|
||||
|
||||
private static final HdmiDeviceInfo DEVICE_INFO_AVR =
|
||||
new HdmiDeviceInfo(ADDR_AUDIO_SYSTEM, PHYSICAL_ADDRESS_AVR, PORT_1,
|
||||
HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM, VENDOR_ID_AVR, "Audio");
|
||||
private static final HdmiDeviceInfo DEVICE_INFO_PLAYER =
|
||||
new HdmiDeviceInfo(ADDR_PLAYBACK_1, PHYSICAL_ADDRESS_PLAYER, PORT_1,
|
||||
HdmiDeviceInfo.DEVICE_PLAYBACK, VENDOR_ID_AVR, "Player");
|
||||
private static final HdmiCecMessage ROUTING_INFORMATION_TUNER = new HdmiCecMessage(
|
||||
ADDR_UNREGISTERED, ADDR_BROADCAST, MESSAGE_ROUTING_INFORMATION, TUNER_PARAM);
|
||||
private static final HdmiCecMessage ROUTING_INFORMATION_PLAYER = new HdmiCecMessage(
|
||||
ADDR_UNREGISTERED, ADDR_BROADCAST, MESSAGE_ROUTING_INFORMATION, PLAYER_PARAM);
|
||||
private static final HdmiCecMessage ACTIVE_SOURCE_TUNER = new HdmiCecMessage(
|
||||
ADDR_TUNER_1, ADDR_BROADCAST, MESSAGE_ACTIVE_SOURCE, TUNER_PARAM);
|
||||
private static final HdmiCecMessage ACTIVE_SOURCE_PLAYER = new HdmiCecMessage(
|
||||
ADDR_PLAYBACK_1, ADDR_BROADCAST, MESSAGE_ACTIVE_SOURCE, PLAYER_PARAM);
|
||||
|
||||
private HdmiControlService mHdmiControlService;
|
||||
private HdmiCecController mHdmiCecController;
|
||||
private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv;
|
||||
private FakeNativeWrapper mNativeWrapper;
|
||||
private Looper mMyLooper;
|
||||
private TestLooper mTestLooper = new TestLooper();
|
||||
private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
|
||||
|
||||
@Mock
|
||||
private IPowerManager mIPowerManagerMock;
|
||||
@Mock
|
||||
private IThermalService mIThermalServiceMock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
Context context = InstrumentationRegistry.getTargetContext();
|
||||
mMyLooper = mTestLooper.getLooper();
|
||||
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
|
||||
mIThermalServiceMock, new Handler(mMyLooper));
|
||||
|
||||
HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
|
||||
|
||||
mHdmiControlService =
|
||||
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
|
||||
@Override
|
||||
boolean isControlEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void wakeUp() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeStringSystemProperty(String key, String value) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isPowerStandbyOrTransient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PowerManager getPowerManager() {
|
||||
return powerManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HdmiCecConfig getHdmiCecConfig() {
|
||||
return hdmiCecConfig;
|
||||
}
|
||||
};
|
||||
|
||||
mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
|
||||
mHdmiCecLocalDeviceTv.init();
|
||||
mHdmiControlService.setIoLooper(mMyLooper);
|
||||
mNativeWrapper = new FakeNativeWrapper();
|
||||
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
|
||||
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
|
||||
mHdmiControlService.setCecController(mHdmiCecController);
|
||||
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
|
||||
mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
|
||||
mLocalDevices.add(mHdmiCecLocalDeviceTv);
|
||||
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
|
||||
hdmiPortInfos[0] =
|
||||
new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, PHYSICAL_ADDRESS_AVR,
|
||||
true, false, false);
|
||||
mNativeWrapper.setPortInfo(hdmiPortInfos);
|
||||
mHdmiControlService.initService();
|
||||
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
|
||||
mNativeWrapper.setPhysicalAddress(0x0000);
|
||||
mTestLooper.dispatchAll();
|
||||
mNativeWrapper.clearResultMessages();
|
||||
mHdmiControlService.getHdmiCecNetwork().addCecDevice(DEVICE_INFO_AVR);
|
||||
}
|
||||
|
||||
private static class TestActionTimer implements ActionTimer {
|
||||
private int mState;
|
||||
|
||||
@Override
|
||||
public void sendTimerMessage(int state, long delayMillis) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTimerMessage() {
|
||||
}
|
||||
|
||||
private int getState() {
|
||||
return mState;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestInputSelectCallback extends IHdmiControlCallback.Stub {
|
||||
private final List<Integer> mCallbackResult = new ArrayList<Integer>();
|
||||
|
||||
@Override
|
||||
public void onComplete(int result) {
|
||||
mCallbackResult.add(result);
|
||||
}
|
||||
|
||||
private int getResult() {
|
||||
assert (mCallbackResult.size() == 1);
|
||||
return mCallbackResult.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static RoutingControlAction createRoutingControlAction(HdmiCecLocalDeviceTv localDevice,
|
||||
TestInputSelectCallback callback) {
|
||||
return new RoutingControlAction(localDevice, PHYSICAL_ADDRESS_AVR, callback);
|
||||
}
|
||||
|
||||
// Routing control succeeds against the device connected directly to the port. Action
|
||||
// won't get any <Routing Information> in this case. It times out on <Routing Information>,
|
||||
// regards the directly connected one as the new routing path to switch to.
|
||||
@Test
|
||||
public void testRoutingControl_succeedForDirectlyConnectedDevice() {
|
||||
TestInputSelectCallback callback = new TestInputSelectCallback();
|
||||
TestActionTimer actionTimer = new TestActionTimer();
|
||||
mHdmiControlService.getHdmiCecNetwork().addCecDevice(DEVICE_INFO_AVR);
|
||||
|
||||
RoutingControlAction action = createRoutingControlAction(mHdmiCecLocalDeviceTv, callback);
|
||||
action.setActionTimer(actionTimer);
|
||||
action.start();
|
||||
assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_ROUTING_INFORMATION);
|
||||
|
||||
action.handleTimerEvent(actionTimer.getState());
|
||||
mTestLooper.dispatchAll();
|
||||
HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(
|
||||
ADDR_TV, PHYSICAL_ADDRESS_AVR);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(setStreamPath);
|
||||
}
|
||||
|
||||
// Succeeds by receiving a couple of <Routing Information> commands, followed by
|
||||
// <Set Stream Path> going out in the end.
|
||||
@Test
|
||||
public void testRoutingControl_succeedForDeviceBehindSwitch() {
|
||||
TestInputSelectCallback callback = new TestInputSelectCallback();
|
||||
TestActionTimer actionTimer = new TestActionTimer();
|
||||
mHdmiControlService.getHdmiCecNetwork().addCecDevice(DEVICE_INFO_PLAYER);
|
||||
RoutingControlAction action = createRoutingControlAction(mHdmiCecLocalDeviceTv, callback);
|
||||
action.setActionTimer(actionTimer);
|
||||
action.start();
|
||||
|
||||
assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_ROUTING_INFORMATION);
|
||||
|
||||
action.processCommand(ROUTING_INFORMATION_TUNER);
|
||||
action.processCommand(ROUTING_INFORMATION_PLAYER);
|
||||
|
||||
action.handleTimerEvent(actionTimer.getState());
|
||||
mTestLooper.dispatchAll();
|
||||
HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(
|
||||
ADDR_TV, PHYSICAL_ADDRESS_PLAYER);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(setStreamPath);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user