summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/hdmi/Constants.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java46
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java171
3 files changed, 155 insertions, 69 deletions
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index ba5ee0231753..dea9309d550b 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -295,6 +295,13 @@ final class Constants {
"persist.sys.hdmi.last_system_audio_control";
/**
+ * Property to indicate if device supports ARC or not
+ * <p>Default is true.
+ */
+ static final String PROPERTY_ARC_SUPPORT =
+ "persist.sys.hdmi.property_arc_support";
+
+ /**
* Property to save the audio port to switch to when system audio control is on.
* <P>Audio system should switch to this port when cec active source is not its child in the tree
* or is not itself.
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 7aab75090b19..ca85249b1f87 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -189,15 +189,14 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
@ServiceThreadOnly
protected boolean handleRequestArcInitiate(HdmiCecMessage message) {
assertRunOnServiceThread();
- // TODO(b/80296911): Check if ARC supported.
-
- // TODO(b/80296911): Check if port is ready to accept.
-
- // TODO(b/80296911): if both true, activate ARC functinality and
- mService.sendCecCommand(
- HdmiCecMessageBuilder.buildInitiateArc(mAddress, message.getSource()));
- // TODO(b/80296911): else, send <Feature Abort>["Unrecongnized opcode"]
-
+ if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) {
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+ } else if (!isDirectConnectToTv()) {
+ HdmiLogger.debug("AVR device is not directly connected with TV");
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+ } else {
+ addAndStartAction(new ArcInitiationActionFromAvr(this));
+ }
return true;
}
@@ -205,15 +204,14 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
@ServiceThreadOnly
protected boolean handleRequestArcTermination(HdmiCecMessage message) {
assertRunOnServiceThread();
- // TODO(b/80297105): Check if ARC supported.
-
- // TODO(b/80297105): Check is currently in arc.
-
- // TODO(b/80297105): If both true, deactivate ARC functionality and
- mService.sendCecCommand(
- HdmiCecMessageBuilder.buildTerminateArc(mAddress, message.getSource()));
- // TODO(b/80297105): else, send <Feature Abort>["Unrecongnized opcode"]
-
+ if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) {
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+ } else if (!isArcEnabled()) {
+ HdmiLogger.debug("ARC is not established between TV and AVR device");
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+ } else {
+ addAndStartAction(new ArcTerminationActionFromAvr(this));
+ }
return true;
}
@@ -377,6 +375,11 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
// TODO(b/111396634): switch input according to PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT
}
+ protected boolean isDirectConnectToTv() {
+ int myPhysicalAddress = mService.getPhysicalAddress();
+ return (myPhysicalAddress & Constants.ROUTING_PATH_TOP_MASK) == myPhysicalAddress;
+ }
+
private void updateAudioManagerForSystemAudio(boolean on) {
int device = mService.getAudioManager().setHdmiSystemAudioSupported(on);
HdmiLogger.debug("[A]UpdateSystemAudio mode[on=%b] output=[%X]", on, device);
@@ -435,4 +438,11 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
void setTvSystemAudioModeSupport(boolean supported) {
mTvSystemAudioModeSupport = supported;
}
+
+ @VisibleForTesting
+ protected boolean isArcEnabled() {
+ synchronized (mLock) {
+ return mArcEstablished;
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 6845b2a9a5cc..5e7a2522f025 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -24,10 +24,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.media.AudioManager;
import android.os.Looper;
+import android.os.SystemProperties;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
+import java.util.List;
import java.util.ArrayList;
+import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -100,12 +103,19 @@ public class HdmiCecLocalDeviceAudioSystemTest {
default:
}
}
+
+ @Override
+ public void setWiredDeviceConnectionState(
+ int type, int state, String address, String name) {
+ // Do nothing.
+ }
};
}
@Override
void wakeUp() {}
};
+
mMyLooper = mTestLooper.getLooper();
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
mHdmiCecLocalDeviceAudioSystem.init();
@@ -121,6 +131,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
// No TV device interacts with AVR so system audio control won't be turned on here
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
+ SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "true");
}
@Test
@@ -135,7 +146,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
HdmiCecMessage messageGive =
HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
@@ -147,33 +158,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
HdmiCecMessage messageGive =
HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
- mTestLooper.dispatchAll();
- assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- }
-
- @Test
- public void handleRequestArcInitiate() {
- // TODO(b/80296911): Add tests when finishing handler impl.
- HdmiCecMessage expectedMessage =
- HdmiCecMessageBuilder.buildInitiateArc(ADDR_AUDIO_SYSTEM, ADDR_TV);
- HdmiCecMessage message =
- HdmiCecMessageBuilder.buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
- assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
- .isEqualTo(true);
- mTestLooper.dispatchAll();
- assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- }
-
- @Test
- public void handleRequestArcTermination() {
- // TODO(b/80297105): Add tests when finishing handler impl.
- HdmiCecMessage expectedMessage =
- HdmiCecMessageBuilder.buildTerminateArc(ADDR_AUDIO_SYSTEM, ADDR_TV);
- HdmiCecMessage messageRequestOff =
- HdmiCecMessageBuilder.buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
- assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(messageRequestOff))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
@@ -189,25 +174,25 @@ public class HdmiCecLocalDeviceAudioSystemTest {
HdmiCecMessage expectedMessage =
HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
// Check if correctly turned on
expectedMessage =
HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, true);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleSetSystemAudioMode(messageSet))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- assertThat(mMusicMute).isEqualTo(false);
+ assertThat(mMusicMute).isFalse();
}
@Test
public void handleSystemAudioModeRequest_turnOffByTv() {
- assertThat(mMusicMute).isEqualTo(false);
+ assertThat(mMusicMute).isFalse();
// Check if feature correctly turned off
HdmiCecMessage messageGive =
HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
@@ -218,16 +203,16 @@ public class HdmiCecLocalDeviceAudioSystemTest {
HdmiCecMessageBuilder.buildSetSystemAudioMode(
ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(messageRequestOff))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
expectedMessage =
HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- assertThat(mMusicMute).isEqualTo(true);
+ assertThat(mMusicMute).isTrue();
}
@Test
@@ -241,7 +226,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
HdmiCecMessageBuilder.buildSetSystemAudioMode(
ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- assertThat(mMusicMute).isEqualTo(true);
+ assertThat(mMusicMute).isTrue();
}
@Test
@@ -292,37 +277,38 @@ public class HdmiCecLocalDeviceAudioSystemTest {
public void handleActiveSource_updateActiveSource() {
HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
ActiveSource expectedActiveSource = new ActiveSource(ADDR_TV, 0x0000);
- assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message)).isEqualTo(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message))
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().equals(expectedActiveSource))
- .isEqualTo(true);
+ .isTrue();
}
@Test
public void terminateSystemAudioMode_systemAudioModeOff() {
mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(false);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(false);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
mMusicMute = false;
HdmiCecMessage message =
HdmiCecMessageBuilder.buildSetSystemAudioMode(
ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
mHdmiCecLocalDeviceAudioSystem.terminateSystemAudioMode();
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(false);
- assertThat(mMusicMute).isEqualTo(false);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
+ assertThat(mMusicMute).isFalse();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(message);
}
@Test
public void terminateSystemAudioMode_systemAudioModeOn() {
mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(true);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isTrue();
mMusicMute = false;
HdmiCecMessage expectedMessage =
HdmiCecMessageBuilder.buildSetSystemAudioMode(
ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
mHdmiCecLocalDeviceAudioSystem.terminateSystemAudioMode();
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(false);
- assertThat(mMusicMute).isEqualTo(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
+ assertThat(mMusicMute).isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
@@ -332,7 +318,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
int targetPhysicalAddress = 0x1000;
mNativeWrapper.setPhysicalAddress(0x1000);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(true);
+ .isTrue();
}
@Test
@@ -340,7 +326,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
int targetPhysicalAddress = 0x1100;
mNativeWrapper.setPhysicalAddress(0x1000);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(true);
+ .isTrue();
}
@Test
@@ -348,21 +334,104 @@ public class HdmiCecLocalDeviceAudioSystemTest {
int targetPhysicalAddress = 0x3000;
mNativeWrapper.setPhysicalAddress(0x2000);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
targetPhysicalAddress = 0x2200;
mNativeWrapper.setPhysicalAddress(0x3300);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
targetPhysicalAddress = 0x2213;
mNativeWrapper.setPhysicalAddress(0x2212);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
targetPhysicalAddress = 0x2340;
mNativeWrapper.setPhysicalAddress(0x2310);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
+ }
+
+ @Test
+ public void handleRequestArcInitiate_isNotDirectConnectedToTv() {
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
+ .buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV,
+ Constants.MESSAGE_REQUEST_ARC_INITIATION,
+ Constants.ABORT_NOT_IN_CORRECT_MODE);
+ mNativeWrapper.setPhysicalAddress(0x1100);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+ }
+
+ @Test
+ public void handleRequestArcInitiate_startArcInitiationActionFromAvr() {
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ mNativeWrapper.setPhysicalAddress(0x1000);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(
+ ArcInitiationActionFromAvr.class);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getActions(ArcInitiationActionFromAvr.class)).isNotEmpty();
+ }
+
+ @Test
+ public void handleRequestArcTerminate_arcIsOn_startTerminationActionFromAvr() {
+ mHdmiCecLocalDeviceAudioSystem.setArcStatus(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isTrue();
+
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(
+ ArcTerminationActionFromAvr.class);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getActions(ArcTerminationActionFromAvr.class)).isNotEmpty();
+ }
+
+ @Test
+ public void handleRequestArcTerminate_arcIsNotOn() {
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
+ .buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV,
+ Constants.MESSAGE_REQUEST_ARC_TERMINATION,
+ Constants.ABORT_NOT_IN_CORRECT_MODE);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+ }
+
+ @Test
+ public void handleRequestArcInit_arcIsNotSupported() {
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
+ .buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV,
+ Constants.MESSAGE_REQUEST_ARC_INITIATION,
+ Constants.ABORT_UNRECOGNIZED_OPCODE);
+ SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "false");
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
}