Loading services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java +18 −3 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } }); } Loading @@ -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); } } services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +10 −2 Original line number Diff line number Diff line Loading @@ -457,9 +457,17 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } else if (!isArcEnabled()) { HdmiLogger.debug("ARC is not established between TV and AVR device"); return Constants.ABORT_NOT_IN_CORRECT_MODE; } else { 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; } } Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +19 −5 Original line number Diff line number Diff line Loading @@ -878,17 +878,31 @@ 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); } } /** * Checks if the Device Discovery is handled by the local device playback. Loading services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java +45 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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, Loading @@ -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 Loading @@ -149,6 +169,7 @@ public class ArcTerminationActionFromAvrTest { mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT); } @Test Loading @@ -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); } } services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -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 = Loading Loading @@ -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); } } } Loading
services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java +18 −3 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } }); } Loading @@ -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); } }
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +10 −2 Original line number Diff line number Diff line Loading @@ -457,9 +457,17 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { } else if (!isArcEnabled()) { HdmiLogger.debug("ARC is not established between TV and AVR device"); return Constants.ABORT_NOT_IN_CORRECT_MODE; } else { 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; } } Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +19 −5 Original line number Diff line number Diff line Loading @@ -878,17 +878,31 @@ 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); } } /** * Checks if the Device Discovery is handled by the local device playback. Loading
services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java +45 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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, Loading @@ -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 Loading @@ -149,6 +169,7 @@ public class ArcTerminationActionFromAvrTest { mTestLooper.dispatchAll(); assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse(); assertThat(mCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT); } @Test Loading @@ -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); } }
services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -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 = Loading Loading @@ -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); } } }