From 4173335baffc84a496d69e2ce4219771bc8bd08f Mon Sep 17 00:00:00 2001 From: Nathalie Le Clair Date: Mon, 29 Nov 2021 16:51:49 +0100 Subject: [PATCH] Inform AudioManager about ARC SADs When an ARC connection is established, the SAD query is triggered and the result is sent to AudioManager, together with the ARC connection state. Bug: 199846933 Test: atest HdmiCecLocalDeviceTvTest Change-Id: Ic598136625da6958aee725b57ecada26ea0217d7 --- .../server/hdmi/HdmiCecLocalDeviceTv.java | 41 ++++++++++++++----- .../server/hdmi/HdmiCecLocalDeviceTvTest.java | 24 +++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index c2ed24a1136d5..1f411cda4bd3b 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -38,7 +38,10 @@ import android.hardware.hdmi.HdmiRecordSources; import android.hardware.hdmi.HdmiTimerRecordSources; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.tv.cec.V1_0.SendMessageResult; -import android.media.AudioSystem; +import android.media.AudioDescriptor; +import android.media.AudioDeviceAttributes; +import android.media.AudioDeviceInfo; +import android.media.AudioProfile; import android.media.tv.TvInputInfo; import android.media.tv.TvInputManager.TvInputCallback; import android.util.Slog; @@ -55,6 +58,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; /** * Represent a logical device of type TV residing in Android system. @@ -813,12 +817,23 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { HdmiLogger.debug("Set Arc Status[old:%b new:%b]", mArcEstablished, enabled); boolean oldStatus = mArcEstablished; - // 1. Enable/disable ARC circuit. - enableAudioReturnChannel(enabled); - // 2. Notify arc status to audio service. - notifyArcStatusToAudioService(enabled); - // 3. Update arc status; - mArcEstablished = enabled; + if (enabled) { + RequestSadAction action = new RequestSadAction( + this, Constants.ADDR_AUDIO_SYSTEM, + new RequestSadAction.RequestSadCallback() { + @Override + public void onRequestSadDone(List supportedSads) { + enableAudioReturnChannel(enabled); + notifyArcStatusToAudioService(enabled, supportedSads); + mArcEstablished = enabled; + } + }); + addAndStartAction(action); + } else { + enableAudioReturnChannel(enabled); + notifyArcStatusToAudioService(enabled, new ArrayList<>()); + mArcEstablished = enabled; + } return oldStatus; } @@ -840,11 +855,15 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { return mService.isConnected(portId); } - private void notifyArcStatusToAudioService(boolean enabled) { + private void notifyArcStatusToAudioService(boolean enabled, List supportedSads) { // Note that we don't set any name to ARC. - mService.getAudioManager().setWiredDeviceConnectionState( - AudioSystem.DEVICE_OUT_HDMI_ARC, - enabled ? 1 : 0, "", ""); + AudioDeviceAttributes attributes = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_HDMI_ARC, "", "", + new ArrayList(), supportedSads.stream() + .map(sad -> new AudioDescriptor(AudioDescriptor.STANDARD_EDID, + AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE, sad)) + .collect(Collectors.toList())); + mService.getAudioManager().setWiredDeviceConnectionState(attributes, enabled ? 1 : 0); } /** diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index a260a6d349207..0ab5cb54b5d72 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -62,6 +62,23 @@ import java.util.concurrent.TimeUnit; public class HdmiCecLocalDeviceTvTest { private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1; + private static final String[] SADS_NOT_TO_QUERY = new String[]{ + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MPEG1, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_AAC, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DTS, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_ATRAC, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DDP, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DTSHD, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_TRUEHD, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DST, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_WMAPRO, + HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX}; + private static final HdmiCecMessage SAD_QUERY = + HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(ADDR_TV, ADDR_AUDIO_SYSTEM, + new int[]{Constants.AUDIO_CODEC_LPCM, Constants.AUDIO_CODEC_DD, + Constants.AUDIO_CODEC_MP3, Constants.AUDIO_CODEC_MPEG2}); + private HdmiControlService mHdmiControlService; private HdmiCecController mHdmiCecController; private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv; @@ -137,6 +154,10 @@ public class HdmiCecLocalDeviceTvTest { mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress); mTestLooper.dispatchAll(); mTvLogicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(); + for (String sad : SADS_NOT_TO_QUERY) { + mHdmiControlService.getHdmiCecConfig().setIntValue( + sad, HdmiControlManager.QUERY_SAD_DISABLED); + } mNativeWrapper.clearResultMessages(); } @@ -431,6 +452,7 @@ public class HdmiCecLocalDeviceTvTest { ADDR_TV, ADDR_AUDIO_SYSTEM); assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SAD_QUERY); } @Test @@ -452,6 +474,7 @@ public class HdmiCecLocalDeviceTvTest { ADDR_TV, ADDR_AUDIO_SYSTEM); assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SAD_QUERY); } @Test @@ -474,6 +497,7 @@ public class HdmiCecLocalDeviceTvTest { ADDR_TV, ADDR_AUDIO_SYSTEM); assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); } @Test