diff options
8 files changed, 74 insertions, 23 deletions
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 1b787b8bc76d..1b0eb19df598 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -279,9 +279,17 @@ final class Constants { * <p>True means enabling muting logic. * <p>False means never mute device. */ - // TODO(OEM): Change property to ro and set to true to disable muting. static final String PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE = - "persist.sys.hdmi.property_system_audio_mode_muting_enable"; + "ro.hdmi.property_system_audio_mode_muting_enable"; + + /** + * When set to true the HdmiControlService will never request a Logical Address for the + * playback device type. Default is false. + * + * <p> This is useful when HDMI CEC multiple device types is not supported by the cec driver + */ + static final String PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS = + "ro.hdmi.property_hdmi_cec_never_claim_playback_logical_address"; // Set to false to allow playback device to go to suspend mode even // when it's an active source. True by default. diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index d8a2d8928274..20908b6d21e2 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -77,8 +77,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { // TODO(amyjojo) make System Audio Control controllable by users /*mSystemAudioControlFeatureEnabled = mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);*/ - // TODO(b/80297700): set read-only property in config instead of setting here - SystemProperties.set(Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, "false"); mAutoDeviceOff = mService.readBooleanSetting( Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, true); mAutoTvOff = mService.readBooleanSetting( @@ -461,6 +459,13 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { mService.announceSystemAudioModeChange(newSystemAudioMode); } } + // Init arc whenever System Audio Mode is on + // Since some TV like LG don't request ARC on with System Audio Mode on request + if (newSystemAudioMode + && SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true) + && !isArcEnabled() && isDirectConnectToTv()) { + addAndStartAction(new ArcInitiationActionFromAvr(this)); + } } protected void switchToAudioInput() { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index be7588aad45c..e9dd6822366e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -174,7 +174,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { } @ServiceThreadOnly - void setActiveSource(boolean on) { + void setIsActiveSource(boolean on) { assertRunOnServiceThread(); mIsActiveSource = on; if (on) { @@ -228,7 +228,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { // If the path is under the current device, should switch int port = getLocalPortFromPhysicalAddress(physicalAddress); if (port == 0) { - setActiveSource(true); + setIsActiveSource(true); maySendActiveSource(message.getSource()); wakeUpIfActiveSource(); } else if (port > 0) { @@ -263,7 +263,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { } private void maySetActiveSource(int physicalAddress) { - setActiveSource(physicalAddress == mService.getPhysicalAddress()); + setIsActiveSource(physicalAddress == mService.getPhysicalAddress()); } private void wakeUpIfActiveSource() { @@ -334,16 +334,6 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { @Override @ServiceThreadOnly - protected void sendStandby(int deviceId) { - assertRunOnServiceThread(); - - // Playback device can send <Standby> to TV only. Ignore the parameter. - int targetAddress = Constants.ADDR_TV; - mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress)); - } - - @Override - @ServiceThreadOnly protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) { super.disableDevice(initiatedByCec, callback); @@ -352,7 +342,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource( mAddress, mService.getPhysicalAddress())); } - setActiveSource(false); + setIsActiveSource(false); checkIfPendingActionsCleared(); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index f9180b798a77..fed66225f839 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -32,6 +32,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { private static final String TAG = "HdmiCecLocalDeviceSource"; + // Indicate if current device is Active Source or not private boolean mIsActiveSource = false; protected HdmiCecLocalDeviceSource(HdmiControlService service, int deviceType) { @@ -49,6 +50,16 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { } } + @Override + @ServiceThreadOnly + protected void sendStandby(int deviceId) { + assertRunOnServiceThread(); + + // Send standby to TV only for now + int targetAddress = Constants.ADDR_TV; + mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress)); + } + @ServiceThreadOnly void oneTouchPlay(IHdmiControlCallback callback) { assertRunOnServiceThread(); @@ -84,11 +95,10 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { int logicalAddress = message.getSource(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress); - if (physicalAddress != mService.getPhysicalAddress() - || !mActiveSource.equals(activeSource)) { + if (!mActiveSource.equals(activeSource)) { setActiveSource(activeSource); - setActiveSource(false); } + setIsActiveSource(physicalAddress == mService.getPhysicalAddress()); return true; } @@ -104,7 +114,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { } @ServiceThreadOnly - void setActiveSource(boolean on) { + void setIsActiveSource(boolean on) { assertRunOnServiceThread(); mIsActiveSource = on; } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java index 941c321d484a..3f949bab8a2e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java @@ -365,6 +365,20 @@ public class HdmiCecMessageBuilder { } /** + * Build <Routing Information> command. + * + * <p>This is a broadcast message sent to all devices on the bus. + * + * @param src source address of command + * @param physicalAddress physical address of the new active routing path + * @return newly created {@link HdmiCecMessage} + */ + static HdmiCecMessage buildRoutingInformation(int src, int physicalAddress) { + return buildCommand(src, Constants.ADDR_BROADCAST, + Constants.MESSAGE_ROUTING_INFORMATION, physicalAddressToParam(physicalAddress)); + } + + /** * Build <Give Device Power Status> command. * * @param src source address of command diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 10f6f922c53c..7e369598a9b1 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -140,6 +140,10 @@ public class HdmiControlService extends SystemService { static final int STANDBY_SCREEN_OFF = 0; static final int STANDBY_SHUTDOWN = 1; + private static final boolean isHdmiCecNeverClaimPlaybackLogicAddr = + SystemProperties.getBoolean( + Constants.PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS, false); + /** * Interface to report send result. */ @@ -639,6 +643,10 @@ public class HdmiControlService extends SystemService { // A container for [Device type, Local device info]. ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); for (int type : mLocalDevices) { + if (type == HdmiDeviceInfo.DEVICE_PLAYBACK + && isHdmiCecNeverClaimPlaybackLogicAddr) { + continue; + } HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type); if (localDevice == null) { localDevice = HdmiCecLocalDevice.create(this, type); @@ -1003,6 +1011,10 @@ public class HdmiControlService extends SystemService { if (connected && !isTvDevice()) { ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); for (int type : mLocalDevices) { + if (type == HdmiDeviceInfo.DEVICE_PLAYBACK + && isHdmiCecNeverClaimPlaybackLogicAddr) { + continue; + } HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type); if (localDevice == null) { localDevice = HdmiCecLocalDevice.create(this, type); @@ -1651,6 +1663,9 @@ public class HdmiControlService extends SystemService { } HdmiCecLocalDevice device = mCecController.getLocalDevice(deviceType); if (device == null) { + device = audioSystem(); + } + if (device == null) { Slog.w(TAG, "Local device not available"); return; } diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java index c7ba7ccbd9bb..48c71d8b738a 100644 --- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java +++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java @@ -85,7 +85,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction { private void broadcastActiveSource() { sendCommand(HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(), getSourcePath())); // Because only source device can create this action, it's safe to cast. - source().setActiveSource(true); + source().setIsActiveSource(true); } private void queryDevicePowerStatus() { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java index c7809d3f2f29..ef974f2e01bb 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; import static com.android.server.hdmi.Constants.ADDR_TV; + import static com.google.common.truth.Truth.assertThat; import android.hardware.hdmi.HdmiDeviceInfo; @@ -51,6 +52,14 @@ public class HdmiCecMessageBuilderTest { assertThat(message).isEqualTo(buildMessage("05:A4:06:01")); } + @Test + public void buildRoutingInformation() { + HdmiCecMessage message = + HdmiCecMessageBuilder.buildRoutingInformation( + ADDR_AUDIO_SYSTEM, 0x2100); + assertThat(message).isEqualTo(buildMessage("5F:81:21:00")); + } + /** * Build a CEC message from a hex byte string with bytes separated by {@code :}. * |