From 02f3115178b161604b8d78561d99b4bad9c54b64 Mon Sep 17 00:00:00 2001 From: Amy Date: Tue, 28 Aug 2018 15:05:42 -0700 Subject: [PATCH 1/7] Add property to never claim playback logic address This supports handling OneTouchPlay without player logical address ag/4891910 Test: local test. Change-Id: I4af65fb251b240c2487f6b4b336cb70fc52837a0 --- .../core/java/com/android/server/hdmi/Constants.java | 9 +++++++++ .../com/android/server/hdmi/HdmiControlService.java | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 1b787b8bc76db..9d66165294174 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -283,6 +283,15 @@ final class Constants { static final String PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE = "persist.sys.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. + * + *

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. static final String PROPERTY_KEEP_AWAKE = "persist.sys.hdmi.keep_awake"; diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 10f6f922c53cf..2f3d75e2fb840 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 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 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); From 6cef86ca76ec26f2e6edfa8bd418e1f1fc892a45 Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 30 Aug 2018 19:06:47 -0700 Subject: [PATCH 2/7] Fix HandleActiveSource logic ag/4912469 Test: local test Change-Id: I399cd254765d8a200f252b6b89fb85e570ca6155 --- .../com/android/server/hdmi/HdmiCecLocalDeviceSource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index f9180b798a77b..c2e2d41d975d5 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -84,11 +84,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); } + setActiveSource(physicalAddress == mService.getPhysicalAddress()); return true; } From d76888aa03bc12efdfd4ce735813fce92ad6a0b1 Mon Sep 17 00:00:00 2001 From: Amy Date: Fri, 31 Aug 2018 11:31:38 -0700 Subject: [PATCH 3/7] Add RoutingInformation CEC message builder. ag/4918461 Test: atest com.android.server.hdmi Change-Id: I945c23cf213986b2b26f2c233931c703f6303e8d --- .../android/server/hdmi/HdmiCecMessageBuilder.java | 14 ++++++++++++++ .../server/hdmi/HdmiCecMessageBuilderTest.java | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java index 941c321d484ac..3f949bab8a2e4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java @@ -364,6 +364,20 @@ public class HdmiCecMessageBuilder { param); } + /** + * Build <Routing Information> command. + * + *

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. * 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 c7809d3f2f296..ef974f2e01bba 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 :}. * From 9a59d9c97d140d3c5cd256e0a8e3cd62387b44a3 Mon Sep 17 00:00:00 2001 From: Amy Date: Fri, 31 Aug 2018 13:47:24 -0700 Subject: [PATCH 4/7] Rename setActiveSource(Boolean) to be different from setActiveSource(ActiveSource). ag/4918867 Test: local test. Change-Id: I63c52c8eabbbdaa8599efe859cb48d6b6100cff7 --- .../android/server/hdmi/HdmiCecLocalDevicePlayback.java | 8 ++++---- .../com/android/server/hdmi/HdmiCecLocalDeviceSource.java | 5 +++-- .../java/com/android/server/hdmi/OneTouchPlayAction.java | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index be7588aad45ca..a528e9676e786 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() { @@ -352,7 +352,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 c2e2d41d975d5..9fc13082c59e0 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) { @@ -87,7 +88,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { if (!mActiveSource.equals(activeSource)) { setActiveSource(activeSource); } - setActiveSource(physicalAddress == mService.getPhysicalAddress()); + setIsActiveSource(physicalAddress == mService.getPhysicalAddress()); return true; } @@ -103,7 +104,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/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java index c7ba7ccbd9bb7..48c71d8b738a8 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() { From 437bfb3278dcaf6cb93490a4589406f4cf2767f0 Mon Sep 17 00:00:00 2001 From: Amy Date: Wed, 5 Sep 2018 14:26:56 -0700 Subject: [PATCH 5/7] Make PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE read-only. This property was manually set to false in LocalDevice before. Adding false value in atom.mk and make the property read-only now. ag/4947274 Test: local tested. Bug: 80297700 Change-Id: Ibf9890233b111653b340c381d86639da1086d9a0 --- services/core/java/com/android/server/hdmi/Constants.java | 3 +-- .../com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 9d66165294174..1b0eb19df598e 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -279,9 +279,8 @@ final class Constants { *

True means enabling muting logic. *

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 diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index d8a2d89282744..0b650b104bb0f 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( From acc1dab9390d0fdb85680cc613c3cd2197a6cd67 Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 6 Sep 2018 17:09:51 -0700 Subject: [PATCH 6/7] Init ARC when system audio mode on in case TV won't request ARC on. ag/4959067 Test: local test. Change-Id: I39d7c849e777b78399ae7ac216c433a50d2e02ca --- .../android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 0b650b104bb0f..20908b6d21e2e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -459,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() { From 777abd72858e425a62a9bdf2be6a29f9b7269413 Mon Sep 17 00:00:00 2001 From: Amy Date: Mon, 10 Sep 2018 16:11:33 -0700 Subject: [PATCH 7/7] Enable sendStandby for device not supporting CEC multi device type. ag/4986713 Test: local test Bug: 114302332 Change-Id: I73b958daf40d0e86174e713053c539c666fe1672 --- .../server/hdmi/HdmiCecLocalDevicePlayback.java | 10 ---------- .../android/server/hdmi/HdmiCecLocalDeviceSource.java | 10 ++++++++++ .../com/android/server/hdmi/HdmiControlService.java | 3 +++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index a528e9676e786..e9dd6822366eb 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -332,16 +332,6 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { return Constants.ADDR_TV; } - @Override - @ServiceThreadOnly - protected void sendStandby(int deviceId) { - assertRunOnServiceThread(); - - // Playback device can send 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) { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 9fc13082c59e0..fed66225f839c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -50,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(); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 2f3d75e2fb840..7e369598a9b1c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -1662,6 +1662,9 @@ public class HdmiControlService extends SystemService { return; } HdmiCecLocalDevice device = mCecController.getLocalDevice(deviceType); + if (device == null) { + device = audioSystem(); + } if (device == null) { Slog.w(TAG, "Local device not available"); return;