Merge "HDMI: More reliable DSM setting disabling"
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
|
||||
/**
|
||||
@@ -33,6 +35,10 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {
|
||||
super(source);
|
||||
}
|
||||
|
||||
ArcTerminationActionFromAvr(HdmiCecLocalDevice source, IHdmiControlCallback callback) {
|
||||
super(source, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean start() {
|
||||
mState = STATE_WAITING_FOR_INITIATE_ARC_RESPONSE;
|
||||
@@ -47,10 +53,19 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {
|
||||
return false;
|
||||
}
|
||||
switch (cmd.getOpcode()) {
|
||||
case Constants.MESSAGE_FEATURE_ABORT:
|
||||
int originalOpcode = cmd.getParams()[0] & 0xFF;
|
||||
if (originalOpcode == Constants.MESSAGE_TERMINATE_ARC) {
|
||||
mState = STATE_ARC_TERMINATED;
|
||||
audioSystem().processArcTermination();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Constants.MESSAGE_REPORT_ARC_TERMINATED:
|
||||
mState = STATE_ARC_TERMINATED;
|
||||
audioSystem().processArcTermination();
|
||||
finish();
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -79,7 +94,7 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {
|
||||
audioSystem().setArcStatus(false);
|
||||
}
|
||||
HdmiLogger.debug("Terminate ARC was not successfully sent.");
|
||||
finish();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -88,6 +103,6 @@ public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {
|
||||
// Disable ARC if TV didn't respond with <Report ARC Terminated> in time.
|
||||
audioSystem().setArcStatus(false);
|
||||
HdmiLogger.debug("handleTerminateArcTimeout");
|
||||
finish();
|
||||
finishWithCallback(HdmiControlManager.RESULT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,8 +458,16 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
HdmiLogger.debug("ARC is not established between TV and AVR device");
|
||||
return Constants.ABORT_NOT_IN_CORRECT_MODE;
|
||||
} else {
|
||||
removeAction(ArcTerminationActionFromAvr.class);
|
||||
addAndStartAction(new ArcTerminationActionFromAvr(this));
|
||||
if (!getActions(ArcTerminationActionFromAvr.class).isEmpty()
|
||||
&& !getActions(ArcTerminationActionFromAvr.class).get(0).mCallbacks.isEmpty()) {
|
||||
IHdmiControlCallback callback =
|
||||
getActions(ArcTerminationActionFromAvr.class).get(0).mCallbacks.get(0);
|
||||
removeAction(ArcTerminationActionFromAvr.class);
|
||||
addAndStartAction(new ArcTerminationActionFromAvr(this, callback));
|
||||
} else {
|
||||
removeAction(ArcTerminationActionFromAvr.class);
|
||||
addAndStartAction(new ArcTerminationActionFromAvr(this));
|
||||
}
|
||||
return Constants.HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -878,16 +878,30 @@ public class HdmiControlService extends SystemService {
|
||||
Slog.w(TAG, "Device type doesn't support ARC.");
|
||||
return;
|
||||
}
|
||||
boolean isArcEnabled = false;
|
||||
if (settingValue == SOUNDBAR_MODE_DISABLED && audioSystem != null) {
|
||||
if (audioSystem.isArcEnabled()) {
|
||||
audioSystem.addAndStartAction(new ArcTerminationActionFromAvr(audioSystem));
|
||||
}
|
||||
isArcEnabled = audioSystem.isArcEnabled();
|
||||
if (isSystemAudioActivated()) {
|
||||
audioSystem.terminateSystemAudioMode();
|
||||
}
|
||||
if (isArcEnabled) {
|
||||
if (audioSystem.hasAction(ArcTerminationActionFromAvr.class)) {
|
||||
audioSystem.removeAction(ArcTerminationActionFromAvr.class);
|
||||
}
|
||||
audioSystem.addAndStartAction(new ArcTerminationActionFromAvr(audioSystem,
|
||||
new IHdmiControlCallback.Stub() {
|
||||
@Override
|
||||
public void onComplete(int result) {
|
||||
mAddressAllocated = false;
|
||||
initializeCecLocalDevices(INITIATED_BY_SOUNDBAR_MODE);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (!isArcEnabled) {
|
||||
mAddressAllocated = false;
|
||||
initializeCecLocalDevices(INITIATED_BY_SOUNDBAR_MODE);
|
||||
}
|
||||
mAddressAllocated = false;
|
||||
initializeCecLocalDevices(INITIATED_BY_SOUNDBAR_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,8 @@ import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Looper;
|
||||
@@ -52,6 +54,7 @@ public class ArcTerminationActionFromAvrTest {
|
||||
private Context mContextSpy;
|
||||
private HdmiCecLocalDeviceAudioSystem mHdmiCecLocalDeviceAudioSystem;
|
||||
private FakePowerManagerWrapper mPowerManager;
|
||||
private TestCallback mCallback;
|
||||
private ArcTerminationActionFromAvr mAction;
|
||||
|
||||
private FakeNativeWrapper mNativeWrapper;
|
||||
@@ -112,7 +115,9 @@ public class ArcTerminationActionFromAvrTest {
|
||||
}
|
||||
};
|
||||
mHdmiCecLocalDeviceAudioSystem.init();
|
||||
mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem);
|
||||
mCallback = new TestCallback();
|
||||
mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem,
|
||||
mCallback);
|
||||
|
||||
mLocalDevices.add(mHdmiCecLocalDeviceAudioSystem);
|
||||
hdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
|
||||
@@ -121,6 +126,20 @@ public class ArcTerminationActionFromAvrTest {
|
||||
mTestLooper.dispatchAll();
|
||||
}
|
||||
|
||||
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 testSendMessage_sendFailed() {
|
||||
mNativeWrapper.setMessageSendResult(Constants.MESSAGE_TERMINATE_ARC,
|
||||
@@ -133,6 +152,7 @@ public class ArcTerminationActionFromAvrTest {
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc);
|
||||
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
|
||||
assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,6 +169,7 @@ public class ArcTerminationActionFromAvrTest {
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
|
||||
assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -167,5 +188,28 @@ public class ArcTerminationActionFromAvrTest {
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
|
||||
assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReportArcTerminated_featureAbort() {
|
||||
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
|
||||
mTestLooper.dispatchAll();
|
||||
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
|
||||
Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_TV);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(terminateArc);
|
||||
|
||||
HdmiCecMessage arcTerminatedResponse = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
Constants.ADDR_TV,
|
||||
Constants.ADDR_AUDIO_SYSTEM,
|
||||
Constants.MESSAGE_TERMINATE_ARC,
|
||||
Constants.ABORT_REFUSED);
|
||||
|
||||
mNativeWrapper.onCecMessage(arcTerminatedResponse);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
|
||||
assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,6 +534,25 @@ public class HdmiCecLocalDeviceAudioSystemTest {
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleRequestArcTerminate_callbackIsPreserved() throws Exception {
|
||||
TestCallback callback = new TestCallback();
|
||||
|
||||
mHdmiCecLocalDeviceAudioSystem.setArcStatus(true);
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isTrue();
|
||||
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(
|
||||
new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem, callback));
|
||||
|
||||
HdmiCecMessage message =
|
||||
HdmiCecMessageBuilder.buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
|
||||
.isEqualTo(Constants.HANDLED);
|
||||
|
||||
mTestLooper.dispatchAll();
|
||||
assertThat(mHdmiCecLocalDeviceAudioSystem.getActions(
|
||||
ArcTerminationActionFromAvr.class).get(0).mCallbacks.get(0)).isEqualTo(callback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleRequestArcInit_arcIsNotSupported() throws Exception {
|
||||
HdmiCecMessage message =
|
||||
@@ -880,4 +899,13 @@ public class HdmiCecLocalDeviceAudioSystemTest {
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(
|
||||
systemAudioModeRequest_fromAudioSystem);
|
||||
}
|
||||
|
||||
private static class TestCallback extends IHdmiControlCallback.Stub {
|
||||
private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>();
|
||||
|
||||
@Override
|
||||
public void onComplete(int result) {
|
||||
mCallbackResult.add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1036,6 +1036,7 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void setSoundbarMode_enabled_addAudioSystemLocalDevice() {
|
||||
mHdmiControlServiceSpy.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
|
||||
// Initialize the local devices excluding the audio system.
|
||||
mHdmiControlServiceSpy.clearCecLocalDevices();
|
||||
mLocalDevices.remove(mAudioSystemDeviceSpy);
|
||||
@@ -1053,6 +1054,7 @@ public class HdmiControlServiceTest {
|
||||
|
||||
@Test
|
||||
public void setSoundbarMode_disabled_removeAudioSystemLocalDevice() {
|
||||
mHdmiControlServiceSpy.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
|
||||
// Initialize the local devices excluding the audio system.
|
||||
mHdmiControlServiceSpy.clearCecLocalDevices();
|
||||
mLocalDevices.remove(mAudioSystemDeviceSpy);
|
||||
@@ -1073,6 +1075,10 @@ public class HdmiControlServiceTest {
|
||||
HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
|
||||
HdmiControlManager.SOUNDBAR_MODE_DISABLED);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
// Wait for ArcTerminationActionFromAvr timeout for the logical address allocation to start.
|
||||
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
assertThat(mHdmiControlServiceSpy.audioSystem()).isNull();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user