Merge changes I8514bcc0,I91d20fd3,Iefc324ba,I29676ef7,I5c3d172f
* changes: Terminate ARC when eARC gets enabled on the RX device Terminate ARC before enabling eARC in the HAL Update ARC state based on eARC status updates Add callback to startArcAction Block new ARC connections during eARC connection
This commit is contained in:
committed by
Android (Google) Code Review
commit
ad7b8ebeeb
@@ -899,10 +899,16 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
|
||||
@ServiceThreadOnly
|
||||
void startArcAction(boolean enabled) {
|
||||
startArcAction(enabled, null);
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
void startArcAction(boolean enabled, IHdmiControlCallback callback) {
|
||||
assertRunOnServiceThread();
|
||||
HdmiDeviceInfo info = getAvrDeviceInfo();
|
||||
if (info == null) {
|
||||
Slog.w(TAG, "Failed to start arc action; No AVR device.");
|
||||
invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
if (!canStartArcUpdateAction(info.getLogicalAddress(), enabled)) {
|
||||
@@ -910,19 +916,37 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
if (enabled && !isConnectedToArcPort(info.getPhysicalAddress())) {
|
||||
displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT);
|
||||
}
|
||||
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
return;
|
||||
}
|
||||
if (enabled && mService.earcBlocksArcConnection()) {
|
||||
Slog.i(TAG,
|
||||
"ARC connection blocked because eARC connection is established or being "
|
||||
+ "established.");
|
||||
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Terminate opposite action and start action if not exist.
|
||||
// Terminate opposite action and create an action with callback.
|
||||
if (enabled) {
|
||||
removeAction(RequestArcTerminationAction.class);
|
||||
if (!hasAction(RequestArcInitiationAction.class)) {
|
||||
addAndStartAction(new RequestArcInitiationAction(this, info.getLogicalAddress()));
|
||||
if (hasAction(RequestArcInitiationAction.class)) {
|
||||
RequestArcInitiationAction existingInitiationAction =
|
||||
getActions(RequestArcInitiationAction.class).get(0);
|
||||
existingInitiationAction.addCallback(callback);
|
||||
} else {
|
||||
addAndStartAction(
|
||||
new RequestArcInitiationAction(this, info.getLogicalAddress(), callback));
|
||||
}
|
||||
} else {
|
||||
removeAction(RequestArcInitiationAction.class);
|
||||
if (!hasAction(RequestArcTerminationAction.class)) {
|
||||
addAndStartAction(new RequestArcTerminationAction(this, info.getLogicalAddress()));
|
||||
if (hasAction(RequestArcTerminationAction.class)) {
|
||||
RequestArcTerminationAction existingTerminationAction =
|
||||
getActions(RequestArcTerminationAction.class).get(0);
|
||||
existingTerminationAction.addCallback(callback);
|
||||
} else {
|
||||
addAndStartAction(
|
||||
new RequestArcTerminationAction(this, info.getLogicalAddress(), callback));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1010,6 +1034,13 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
protected int handleInitiateArc(HdmiCecMessage message) {
|
||||
assertRunOnServiceThread();
|
||||
|
||||
if (mService.earcBlocksArcConnection()) {
|
||||
Slog.i(TAG,
|
||||
"ARC connection blocked because eARC connection is established or being "
|
||||
+ "established.");
|
||||
return Constants.ABORT_NOT_IN_CORRECT_MODE;
|
||||
}
|
||||
|
||||
if (!canStartArcUpdateAction(message.getSource(), true)) {
|
||||
HdmiDeviceInfo avrDeviceInfo = getAvrDeviceInfo();
|
||||
if (avrDeviceInfo == null) {
|
||||
@@ -1023,9 +1054,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
return Constants.ABORT_REFUSED;
|
||||
}
|
||||
|
||||
// In case where <Initiate Arc> is started by <Request ARC Initiation>
|
||||
// need to clean up RequestArcInitiationAction.
|
||||
removeAction(RequestArcInitiationAction.class);
|
||||
// In case where <Initiate Arc> is started by <Request ARC Initiation>, this message is
|
||||
// handled in RequestArcInitiationAction as well.
|
||||
SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
|
||||
message.getSource(), true);
|
||||
addAndStartAction(action);
|
||||
@@ -1059,9 +1089,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
return Constants.HANDLED;
|
||||
}
|
||||
// Do not check ARC configuration since the AVR might have been already removed.
|
||||
// Clean up RequestArcTerminationAction in case <Terminate Arc> was started by
|
||||
// <Request ARC Termination>.
|
||||
removeAction(RequestArcTerminationAction.class);
|
||||
// In case where <Terminate Arc> is started by <Request ARC Termination>, this
|
||||
// message is handled in RequestArcTerminationAction as well.
|
||||
SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
|
||||
message.getSource(), false);
|
||||
addAndStartAction(action);
|
||||
|
||||
@@ -26,6 +26,7 @@ import static android.hardware.hdmi.HdmiControlManager.SOUNDBAR_MODE_ENABLED;
|
||||
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
|
||||
import static com.android.server.hdmi.Constants.DISABLED;
|
||||
import static com.android.server.hdmi.Constants.ENABLED;
|
||||
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_ARC_PENDING;
|
||||
import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
|
||||
import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING;
|
||||
import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE;
|
||||
@@ -392,7 +393,7 @@ public class HdmiControlService extends SystemService {
|
||||
// and the eARC HAL is present.
|
||||
@GuardedBy("mLock")
|
||||
@VisibleForTesting
|
||||
protected boolean mEarcSupported;
|
||||
private boolean mEarcSupported;
|
||||
|
||||
// Set to true while the eARC feature is enabled.
|
||||
@GuardedBy("mLock")
|
||||
@@ -725,7 +726,7 @@ public class HdmiControlService extends SystemService {
|
||||
if (isEarcEnabled()) {
|
||||
initializeEarc(INITIATED_BY_BOOT_UP);
|
||||
} else {
|
||||
setEarcEnabledInHal(false);
|
||||
setEarcEnabledInHal(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3236,6 +3237,9 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
|
||||
private void invokeCallback(IHdmiControlCallback callback, int result) {
|
||||
if (callback == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
callback.onComplete(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -3518,7 +3522,7 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
initializeEarc(startReason);
|
||||
} else {
|
||||
setEarcEnabledInHal(false);
|
||||
setEarcEnabledInHal(false, false);
|
||||
}
|
||||
}
|
||||
// TODO: Initialize MHL local devices.
|
||||
@@ -4414,8 +4418,17 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
private void initializeEarc(int initiatedBy) {
|
||||
Slog.i(TAG, "eARC initialized, reason = " + initiatedBy);
|
||||
setEarcEnabledInHal(true);
|
||||
initializeEarcLocalDevice(initiatedBy);
|
||||
|
||||
if (initiatedBy == INITIATED_BY_ENABLE_EARC) {
|
||||
// Since ARC and eARC cannot be connected simultaneously, we need to terminate ARC
|
||||
// before even enabling eARC.
|
||||
setEarcEnabledInHal(true, true);
|
||||
} else {
|
||||
// On boot, wake-up, and hotplug in, eARC will always be attempted before ARC.
|
||||
// So there is no need to explicitly terminate ARC before enabling eARC.
|
||||
setEarcEnabledInHal(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@@ -4464,13 +4477,14 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
@ServiceThreadOnly
|
||||
private void onEnableEarc() {
|
||||
// This will terminate ARC as well.
|
||||
initializeEarc(INITIATED_BY_ENABLE_EARC);
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
private void onDisableEarc() {
|
||||
disableEarcLocalDevice();
|
||||
setEarcEnabledInHal(false);
|
||||
setEarcEnabledInHal(false, false);
|
||||
clearEarcLocalDevice();
|
||||
}
|
||||
|
||||
@@ -4504,12 +4518,28 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
@ServiceThreadOnly
|
||||
@VisibleForTesting
|
||||
protected void setEarcEnabledInHal(boolean enabled) {
|
||||
protected void setEarcEnabledInHal(boolean enabled, boolean terminateArcFirst) {
|
||||
assertRunOnServiceThread();
|
||||
mEarcController.setEarcEnabled(enabled);
|
||||
mCecController.setHpdSignalType(
|
||||
enabled ? Constants.HDMI_HPD_TYPE_STATUS_BIT : Constants.HDMI_HPD_TYPE_PHYSICAL,
|
||||
mEarcPortId);
|
||||
if (terminateArcFirst) {
|
||||
startArcAction(false, new IHdmiControlCallback.Stub() {
|
||||
@Override
|
||||
public void onComplete(int result) throws RemoteException {
|
||||
// Independently of the result (i.e. independently of whether the ARC RX device
|
||||
// responded with <Terminate ARC> or not), we always end up terminating ARC in
|
||||
// the HAL. As soon as we do that, we can enable eARC in the HAL.
|
||||
mEarcController.setEarcEnabled(enabled);
|
||||
mCecController.setHpdSignalType(
|
||||
enabled ? Constants.HDMI_HPD_TYPE_STATUS_BIT
|
||||
: Constants.HDMI_HPD_TYPE_PHYSICAL,
|
||||
mEarcPortId);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mEarcController.setEarcEnabled(enabled);
|
||||
mCecController.setHpdSignalType(
|
||||
enabled ? Constants.HDMI_HPD_TYPE_STATUS_BIT : Constants.HDMI_HPD_TYPE_PHYSICAL,
|
||||
mEarcPortId);
|
||||
}
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@@ -4540,4 +4570,21 @@ public class HdmiControlService extends SystemService {
|
||||
mEarcLocalDevice.handleEarcCapabilitiesReported(rawCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean earcBlocksArcConnection() {
|
||||
if (mEarcLocalDevice == null) {
|
||||
return false;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
return mEarcLocalDevice.mEarcStatus != HDMI_EARC_STATUS_ARC_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
protected void startArcAction(boolean enabled, IHdmiControlCallback callback) {
|
||||
if (!isTvDeviceEnabled()) {
|
||||
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
} else {
|
||||
tv().startArcAction(enabled, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.hdmi;
|
||||
|
||||
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_ARC_PENDING;
|
||||
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_CONNECTED;
|
||||
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_PENDING;
|
||||
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_IDLE;
|
||||
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
@@ -69,23 +70,36 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
|
||||
HdmiEarcLocalDeviceTx(HdmiControlService service) {
|
||||
super(service, HdmiDeviceInfo.DEVICE_TV);
|
||||
|
||||
synchronized (mLock) {
|
||||
mEarcStatus = HDMI_EARC_STATUS_EARC_PENDING;
|
||||
}
|
||||
mReportCapsHandler = new Handler(service.getServiceLooper());
|
||||
mReportCapsRunnable = new ReportCapsRunnable();
|
||||
}
|
||||
|
||||
protected void handleEarcStateChange(@Constants.EarcStatus int status) {
|
||||
int oldEarcStatus;
|
||||
synchronized (mLock) {
|
||||
HdmiLogger.debug(TAG, "eARC state change [old:%b new %b]", mEarcStatus,
|
||||
status);
|
||||
oldEarcStatus = mEarcStatus;
|
||||
mEarcStatus = status;
|
||||
}
|
||||
|
||||
mReportCapsHandler.removeCallbacksAndMessages(null);
|
||||
if (status == HDMI_EARC_STATUS_IDLE) {
|
||||
notifyEarcStatusToAudioService(false, new ArrayList<>());
|
||||
mService.startArcAction(false, null);
|
||||
} else if (status == HDMI_EARC_STATUS_ARC_PENDING) {
|
||||
notifyEarcStatusToAudioService(false, new ArrayList<>());
|
||||
mService.startArcAction(true, null);
|
||||
} else if (status == HDMI_EARC_STATUS_EARC_PENDING
|
||||
&& oldEarcStatus == HDMI_EARC_STATUS_ARC_PENDING) {
|
||||
mService.startArcAction(false, null);
|
||||
} else if (status == HDMI_EARC_STATUS_EARC_CONNECTED) {
|
||||
if (oldEarcStatus == HDMI_EARC_STATUS_ARC_PENDING) {
|
||||
mService.startArcAction(false, null);
|
||||
}
|
||||
mReportCapsHandler.postDelayed(mReportCapsRunnable, REPORT_CAPS_MAX_DELAY_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
|
||||
/**
|
||||
* Base feature action class for <Request ARC Initiation>/<Request ARC Termination>.
|
||||
@@ -35,41 +37,19 @@ abstract class RequestArcAction extends HdmiCecFeatureAction {
|
||||
*
|
||||
* @param source {@link HdmiCecLocalDevice} instance
|
||||
* @param avrAddress address of AV receiver. It should be AUDIO_SYSTEM type
|
||||
* @param callback callback to inform about the status of the action
|
||||
* @throws IllegalArgumentException if device type of sourceAddress and avrAddress
|
||||
* is invalid
|
||||
*/
|
||||
RequestArcAction(HdmiCecLocalDevice source, int avrAddress) {
|
||||
super(source);
|
||||
RequestArcAction(HdmiCecLocalDevice source, int avrAddress, IHdmiControlCallback callback) {
|
||||
super(source, callback);
|
||||
HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
|
||||
HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mAvrAddress = avrAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean processCommand(HdmiCecMessage cmd) {
|
||||
if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
|
||||
|| !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
|
||||
return false;
|
||||
}
|
||||
int opcode = cmd.getOpcode();
|
||||
switch (opcode) {
|
||||
// Handles only <Feature Abort> here and, both <Initiate ARC> and <Terminate ARC>
|
||||
// are handled in HdmiControlService itself because both can be
|
||||
// received without <Request ARC Initiation> or <Request ARC Termination>.
|
||||
case Constants.MESSAGE_FEATURE_ABORT:
|
||||
int originalOpcode = cmd.getParams()[0] & 0xFF;
|
||||
if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_TERMINATION) {
|
||||
disableArcTransmission();
|
||||
finish();
|
||||
return true;
|
||||
} else if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_INITIATION) {
|
||||
tv().disableArc();
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
RequestArcAction(HdmiCecLocalDevice source, int avrAddress) {
|
||||
this(source, avrAddress, null);
|
||||
}
|
||||
|
||||
protected final void disableArcTransmission() {
|
||||
@@ -86,6 +66,6 @@ abstract class RequestArcAction extends HdmiCecFeatureAction {
|
||||
}
|
||||
HdmiLogger.debug("[T] RequestArcAction.");
|
||||
disableArcTransmission();
|
||||
finish();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
|
||||
/**
|
||||
@@ -35,6 +37,16 @@ final class RequestArcInitiationAction extends RequestArcAction {
|
||||
super(source, avrAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Constructor
|
||||
*
|
||||
* For more details look at {@link RequestArcAction#RequestArcAction}.
|
||||
*/
|
||||
RequestArcInitiationAction(HdmiCecLocalDevice source, int avrAddress,
|
||||
IHdmiControlCallback callback) {
|
||||
super(source, avrAddress, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean start() {
|
||||
// Seq #38
|
||||
@@ -49,10 +61,34 @@ final class RequestArcInitiationAction extends RequestArcAction {
|
||||
if (error != SendMessageResult.SUCCESS) {
|
||||
// Turn off ARC status if <Request ARC Initiation> fails.
|
||||
tv().disableArc();
|
||||
finish();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean processCommand(HdmiCecMessage cmd) {
|
||||
if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
|
||||
|| !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
|
||||
return false;
|
||||
}
|
||||
int opcode = cmd.getOpcode();
|
||||
switch (opcode) {
|
||||
case Constants.MESSAGE_FEATURE_ABORT:
|
||||
int originalOpcode = cmd.getParams()[0] & 0xFF;
|
||||
if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_INITIATION) {
|
||||
tv().disableArc();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Constants.MESSAGE_INITIATE_ARC:
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
// This message still needs to be handled in HdmiCecLocalDeviceTv as well.
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
|
||||
/**
|
||||
@@ -35,6 +37,16 @@ final class RequestArcTerminationAction extends RequestArcAction {
|
||||
super(source, avrAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Constructor
|
||||
*
|
||||
* @see RequestArcAction#RequestArcAction
|
||||
*/
|
||||
RequestArcTerminationAction(HdmiCecLocalDevice source, int avrAddress,
|
||||
IHdmiControlCallback callback) {
|
||||
super(source, avrAddress, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean start() {
|
||||
mState = STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE;
|
||||
@@ -49,10 +61,34 @@ final class RequestArcTerminationAction extends RequestArcAction {
|
||||
// If failed to send <Request ARC Termination>, start "Disabled" ARC
|
||||
// transmission action.
|
||||
disableArcTransmission();
|
||||
finish();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean processCommand(HdmiCecMessage cmd) {
|
||||
if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
|
||||
|| !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
|
||||
return false;
|
||||
}
|
||||
int opcode = cmd.getOpcode();
|
||||
switch (opcode) {
|
||||
case Constants.MESSAGE_FEATURE_ABORT:
|
||||
int originalOpcode = cmd.getParams()[0] & 0xFF;
|
||||
if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_TERMINATION) {
|
||||
disableArcTransmission();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Constants.MESSAGE_TERMINATE_ARC:
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
// This message still needs to be handled in HdmiCecLocalDeviceTv as well.
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.content.Context;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.HdmiPortInfo;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Looper;
|
||||
@@ -96,6 +97,7 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
private int mTvPhysicalAddress;
|
||||
private int mTvLogicalAddress;
|
||||
private boolean mWokenUp;
|
||||
private boolean mEarcBlocksArc;
|
||||
private List<DeviceEventListener> mDeviceEventListeners = new ArrayList<>();
|
||||
|
||||
private class DeviceEventListener {
|
||||
@@ -155,6 +157,11 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isPowerStandbyOrTransient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
AudioManager getAudioManager() {
|
||||
return mAudioManager;
|
||||
@@ -164,6 +171,11 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) {
|
||||
mDeviceEventListeners.add(new DeviceEventListener(device, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean earcBlocksArcConnection() {
|
||||
return mEarcBlocksArc;
|
||||
}
|
||||
};
|
||||
|
||||
mHdmiControlService.setIoLooper(mMyLooper);
|
||||
@@ -175,16 +187,18 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
|
||||
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2];
|
||||
hdmiPortInfos[0] =
|
||||
new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x1000, true, false, false);
|
||||
new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x1000, true, false, false, false);
|
||||
hdmiPortInfos[1] =
|
||||
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true);
|
||||
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true, true);
|
||||
mNativeWrapper.setPortInfo(hdmiPortInfos);
|
||||
mHdmiControlService.initService();
|
||||
mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
|
||||
mPowerManager = new FakePowerManagerWrapper(context);
|
||||
mHdmiControlService.setPowerManager(mPowerManager);
|
||||
mTvPhysicalAddress = 0x0000;
|
||||
mEarcBlocksArc = false;
|
||||
mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress);
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
mHdmiCecLocalDeviceTv = mHdmiControlService.tv();
|
||||
mTvLogicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress();
|
||||
@@ -196,6 +210,20 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
mNativeWrapper.clearResultMessages();
|
||||
}
|
||||
|
||||
private static class TestCallback extends IHdmiControlCallback.Stub {
|
||||
private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>();
|
||||
|
||||
@Override
|
||||
public void onComplete(int result) {
|
||||
mCallbackResult.add(result);
|
||||
}
|
||||
|
||||
private int getResult() {
|
||||
assertThat(mCallbackResult.size()).isEqualTo(1);
|
||||
return mCallbackResult.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialPowerStateIsStandby() {
|
||||
assertThat(mHdmiCecLocalDeviceTv.getPowerStatus()).isEqualTo(
|
||||
@@ -426,9 +454,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void startArcAction_enable_portDoesNotSupportArc() {
|
||||
// Emulate Audio device on port 0x1000 (does not support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true);
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
@@ -445,9 +474,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void startArcAction_disable_portDoesNotSupportArc() {
|
||||
// Emulate Audio device on port 0x1000 (does not support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false);
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
@@ -464,9 +494,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void startArcAction_enable_portSupportsArc() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true);
|
||||
@@ -485,9 +516,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void startArcAction_disable_portSupportsArc() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false);
|
||||
@@ -522,9 +554,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void handleInitiateArc_portDoesNotSupportArc() {
|
||||
// Emulate Audio device on port 0x1000 (does not support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
@@ -544,9 +577,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void handleInitiateArc_portSupportsArc() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
|
||||
@@ -574,6 +608,66 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleTerminateArc_noAudioDevice() {
|
||||
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(terminateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleTerminateArc_portDoesNotSupportArc() {
|
||||
// Emulate Audio device on port 0x1000 (does not support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
|
||||
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(terminateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleTerminateArc_portSupportsArc() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(terminateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsRecordTvScreen() {
|
||||
HdmiCecMessage recordTvScreen = HdmiCecMessage.build(ADDR_RECORDER_1, mTvLogicalAddress,
|
||||
@@ -595,9 +689,10 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED);
|
||||
// Emulate Audio device on port 0x1000 (does not support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecFeatureAction systemAudioAutoInitiationAction =
|
||||
@@ -636,9 +731,9 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
public void hotplugDetectionAction_discoversDeviceAfterMessageReceived() {
|
||||
// Playback 1 sends a message before ACKing a poll
|
||||
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.NACK);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildActiveSource(
|
||||
HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
|
||||
ADDR_PLAYBACK_1, ADDR_TV);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
mNativeWrapper.onCecMessage(activeSource);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// Playback 1 begins ACKing polls, allowing detection by HotplugDetectionAction
|
||||
@@ -812,12 +907,12 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// <Feature Abort>[Not in correct mode] not sent
|
||||
HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_TV,
|
||||
ADDR_PLAYBACK_1,
|
||||
Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL,
|
||||
Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortMessage);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort);
|
||||
|
||||
// <Set Audio Volume Level> uses volume range [0, 100]; STREAM_MUSIC uses range [0, 25]
|
||||
verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(5), anyInt());
|
||||
@@ -838,12 +933,12 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// <Feature Abort>[Not in correct mode] sent
|
||||
HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_TV,
|
||||
ADDR_PLAYBACK_1,
|
||||
Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL,
|
||||
Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbortMessage);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
|
||||
|
||||
// AudioManager not notified of volume change
|
||||
verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), anyInt(),
|
||||
@@ -853,11 +948,11 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
@Test
|
||||
public void tvSendRequestArcTerminationOnSleep() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC)
|
||||
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(hdmiCecMessage);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true);
|
||||
@@ -898,4 +993,560 @@ public class HdmiCecLocalDeviceTvTest {
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_enable_earcBlocksArc() {
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = true;
|
||||
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true);
|
||||
mTestLooper.dispatchAll();
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_enable_earcDoesNotBlockArc() {
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = false;
|
||||
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true);
|
||||
mTestLooper.dispatchAll();
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_disable_earcBlocksArc() {
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = true;
|
||||
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false);
|
||||
mTestLooper.dispatchAll();
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleInitiateArc_earcBlocksArc() {
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = true;
|
||||
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(requestArcInitiation);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
Constants.MESSAGE_INITIATE_ARC,
|
||||
Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleInitiateArc_earcDoesNotBlockArc() {
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = false;
|
||||
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(requestArcInitiation);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
// <Report ARC Initiated> should only be sent after SAD querying is done
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
|
||||
|
||||
// Finish querying SADs
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
|
||||
mNativeWrapper.clearResultMessages();
|
||||
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
|
||||
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleTerminateArc_earcBlocksArc() {
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = true;
|
||||
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(terminateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_noAvr() {
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_portNotConnected() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC)
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
// Emulate port disconnect
|
||||
mNativeWrapper.setPortConnectionStatus(2, false);
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_portDoesNotSupportArc() {
|
||||
// Emulate Audio device on port 0x1000 (Doesn´t support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_indirectPhysicalAddress() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2320, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_earcBlocksArc() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mEarcBlocksArc = true;
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_messageNotAcked() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mNativeWrapper.setMessageSendResult(
|
||||
Constants.MESSAGE_REQUEST_ARC_INITIATION, SendMessageResult.NACK);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_timeout() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
|
||||
mTestLooper.moveTimeForward(TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_featureAbort() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
|
||||
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV,
|
||||
Constants.MESSAGE_REQUEST_ARC_INITIATION,
|
||||
Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
mNativeWrapper.onCecMessage(featureAbort);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_initiation_success() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
|
||||
|
||||
HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
mNativeWrapper.onCecMessage(initiateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_termination_noAvr() {
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_termination_portDoesNotSupportArc() {
|
||||
// Emulate Audio device on port 0x1000 (Doesn´t support ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(1, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_termination_messageNotAcked() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
mNativeWrapper.setMessageSendResult(
|
||||
Constants.MESSAGE_REQUEST_ARC_TERMINATION, SendMessageResult.NACK);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_termination_timeout() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
mTestLooper.moveTimeForward(TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_termination_featureAbort() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV,
|
||||
Constants.MESSAGE_REQUEST_ARC_TERMINATION,
|
||||
Constants.ABORT_NOT_IN_CORRECT_MODE);
|
||||
mNativeWrapper.onCecMessage(featureAbort);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startArcAction_termination_success() {
|
||||
// Emulate Audio device on port 0x2000 (Supports ARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
|
||||
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
mNativeWrapper.onCecMessage(terminateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableEarc_terminateArc() {
|
||||
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
|
||||
mNativeWrapper.setPortConnectionStatus(2, true);
|
||||
HdmiCecMessage reportPhysicalAddress =
|
||||
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
|
||||
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mNativeWrapper.onCecMessage(reportPhysicalAddress);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc(
|
||||
ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV);
|
||||
|
||||
mNativeWrapper.onCecMessage(initiateArc);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
// <Report ARC Initiated> should only be sent after SAD querying is done
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
|
||||
|
||||
// Finish querying SADs
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
|
||||
mNativeWrapper.clearResultMessages();
|
||||
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
|
||||
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
|
||||
mNativeWrapper.clearResultMessages();
|
||||
|
||||
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
|
||||
ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,11 @@ import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -143,6 +145,7 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.setPowerManager(mPowerManager);
|
||||
mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
|
||||
mHdmiControlServiceSpy.setAudioManager(mAudioManager);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
|
||||
mTestLooper.dispatchAll();
|
||||
}
|
||||
@@ -1087,7 +1090,6 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void disableEarc_clearEarcLocalDevice() {
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(
|
||||
new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy));
|
||||
@@ -1100,7 +1102,6 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void disableCec_doNotClearEarcLocalDevice() {
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(
|
||||
new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy));
|
||||
@@ -1113,7 +1114,6 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void enableCec_initializeCecLocalDevices() {
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.setCecEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
@@ -1125,7 +1125,6 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void enableEarc_initializeEarcLocalDevices() {
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
@@ -1137,7 +1136,6 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void disableCec_DoNotInformHalAboutEarc() {
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
|
||||
HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
|
||||
@@ -1147,7 +1145,7 @@ public class HdmiControlServiceTest {
|
||||
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
|
||||
HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(anyBoolean());
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(anyBoolean(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1155,15 +1153,14 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false, false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(eq(true), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1171,14 +1168,13 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
|
||||
HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
|
||||
HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(anyBoolean());
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(anyBoolean(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1186,15 +1182,14 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_DISABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(false);
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true, true);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(eq(false), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1202,13 +1197,15 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
|
||||
HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.initService();
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(false);
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true, false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(eq(false), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1216,13 +1213,12 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_DISABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.initService();
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false, false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(eq(true), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1230,13 +1226,12 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_ENABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.onWakeUp(WAKE_UP_SCREEN_ON);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(false);
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true, false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(eq(false), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1244,13 +1239,106 @@ public class HdmiControlServiceTest {
|
||||
mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
|
||||
HdmiControlManager.SETTING_NAME_EARC_ENABLED,
|
||||
HdmiControlManager.EARC_FEATURE_DISABLED);
|
||||
mHdmiControlServiceSpy.setEarcSupported(true);
|
||||
mTestLooper.dispatchAll();
|
||||
Mockito.clearInvocations(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.onWakeUp(WAKE_UP_SCREEN_ON);
|
||||
mTestLooper.dispatchAll();
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
|
||||
verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false, false);
|
||||
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(eq(true), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcIdle_blocksArcConnection() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_IDLE);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcPending_blocksArcConnection() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_PENDING);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcEnabled_blocksArcConnection() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_CONNECTED);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arcPending_doesNotBlockArcConnection() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcStatusBecomesIdle_terminateArc() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_IDLE);
|
||||
verify(mHdmiControlServiceSpy, times(1)).startArcAction(eq(false), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcStatusBecomesEnabled_doNothing() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_CONNECTED);
|
||||
verify(mHdmiControlServiceSpy, times(0)).startArcAction(anyBoolean(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcStatusBecomesPending_doNothing() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_PENDING);
|
||||
verify(mHdmiControlServiceSpy, times(0)).startArcAction(anyBoolean(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcStatusBecomesNotEnabled_initiateArc() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING);
|
||||
verify(mHdmiControlServiceSpy, times(1)).startArcAction(eq(true), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcStateWasArcPending_becomesEarcPending_terminateArc() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING);
|
||||
mTestLooper.dispatchAll();
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_PENDING);
|
||||
verify(mHdmiControlServiceSpy, times(1)).startArcAction(eq(false), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void earcStateWasArcPending_becomesEarcEnabled_terminateArc() {
|
||||
mHdmiControlServiceSpy.clearEarcLocalDevice();
|
||||
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
|
||||
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING);
|
||||
mTestLooper.dispatchAll();
|
||||
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_CONNECTED);
|
||||
verify(mHdmiControlServiceSpy, times(1)).startArcAction(eq(false), any());
|
||||
}
|
||||
|
||||
protected static class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {
|
||||
|
||||
Reference in New Issue
Block a user