오디오 제어 HAL

오디오 제어 HAL은 Android 9에서 자동차와 관련된 오디오 사용 사례를 지원하기 위해 도입되었습니다. Android 14부터 오디오 제어 HAL은 다음을 지원합니다.

  • 페이드 및 밸런스
  • HAL 오디오 포커스 요청
  • 기기 음소거 및 볼륨 낮추기
  • 오디오 기기 게인 변경
  • 오디오 포트 구성 변경

그림 1은 자동차 오디오 서비스 아키텍처의 대략적인 개요를 보여주며 여기서 자동차 오디오 서비스는 오디오 제어 HAL과 통신합니다.

다중 영역 오디오 구성

그림 1. 다중 영역 오디오 구성

오디오 페이드 및 밸런스

HIDL 오디오 제어 HAL 버전 1은 Android 9에서 자동차 사용 사례의 오디오 페이드 및 밸런스를 지원하기 위해 도입되었습니다. Android에서 이미 제공된 일반 오디오 효과와 별도로 이 메커니즘을 사용하면 시스템 앱에서 CarAudioManager API를 통해 오디오 밸런스 및 페이드를 설정할 수 있습니다.

class CarAudioManager {
       /**
       *   Adjust the relative volume in the front vs back of the vehicle cabin.
       *
       *   @param value in the range -1.0 to 1.0 for fully toward the back through
       *   fully toward the front. 0.0 means evenly balanced.
       */
       @SystemApi
       @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
       public void setFadeTowardFront(float value);

       /**
       *   Adjust the relative volume on the left vs right side of the vehicle cabin.
       *
       *   @param value in the range -1.0 to 1.0 for fully toward the left through
       *   fully toward the right. 0.0 means evenly balanced.
       */
       @SystemApi
       @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
       public void setBalanceTowardRight(float value);
}

이러한 API를 호출하면 해당 오디오 제어 HAL API가 자동차 오디오 서비스에서 호출됩니다.

interface IAudioControl {
       /**
       *   Control the right/left balance setting of the car speakers.
       */
       oneway setBalanceTowardRight(float value);

       /**
       *   Control the fore/aft fade setting of the car speakers.
       */
       oneway setFadeTowardFront(float value);
}

API는 새로운 AIDL HAL 인터페이스 등 모든 버전의 오디오 제어 HAL에서 사용할 수 있습니다.

HAL의 오디오 포커스 요청

AAOS는 Android와 마찬가지로 오디오 포커스에 관한 앱의 적극적인 참여에 의존하여 자동차의 오디오 재생을 관리합니다. 포커스 정보는 볼륨 낮추기를 위해 제어할 스트림을 관리하는 데 사용됩니다. 따라서 오디오 포커스를 더욱 확장하고 자동차 관련 사운드를 Android 환경에 더 잘 통합하기 위해 Android 11에서는 다음 오디오 속성이 도입되었습니다.

  • EMERGENCY
  • SAFETY
  • VEHICLE_STATUS
  • ANNOUNCEMENT

이 변경사항 외에도 Android 외부에서 발생하는 사운드가 오디오 포커스 요청에 참여할 수 있도록 하는 메커니즘이 추가되었습니다. 따라서 HIDL 오디오 제어 HAL 버전 2는 다음과 같이 Android 외부에서 발생하는 포커스 요청을 허용하기 위해 도입되었습니다.

interface IAudioControl {
       /**
       *   Registers focus listener to be used by HAL for requesting and
       *   abandoning audio focus.
       *   @param listener the listener interface
       *   @return closeHandle A handle to unregister observer.
       */
       registerFocusListener(IFocusListener listener)
       generates (ICloseHandle closeHandle);

       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   @param usage The audio usage associated with the focus change
       *   @param zoneId The identifier for the audio zone that the HAL is
       *   playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred
       */
       oneway onAudioFocusChange(bitfield<AudioUsage> usage, int32_t zoneId,
       bitfield<AudioFocusChange> focusChange);
}

여기서 IFocusListener는 다음과 같이 정의됩니다.

interface IFocusListener {
       /**
       *   Called whenever HAL is requesting focus as it is starting to play
       *   audio of a given usage in a specified zone.
       *
       *   @param usage The audio usage associated with the focus request
       *    {@code AttributeUsage}
       *   @param zoneId The identifier for the audio zone where the HAL is
       *    requesting focus
       *   @param focusGain The AudioFocusChange associated with this request.
       */
       oneway requestAudioFocus(bitfield<AudioUsage> usage,
       int32_t zoneId, bitfield<AudioFocusChange> focusGain);
       /**
       *   Called whenever HAL is abandoning focus as it is finished playing audio
       *   of a given usage in a specific zone.
       *
       *   @param usage The audio usage for which the HAL is abandoning focus
       *    {@code AttributeUsage}
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       */
       oneway abandonAudioFocus(bitfield<AudioUsage> usage, int32_t zoneId);
}

위의 API는 각각 HAL에서 오디오 포커스를 요청하고 포기하는 데 사용할 수 있습니다. 응답으로 자동차 오디오 서비스는 오디오 포커스 요청을 고려하고 결과를 IAudioControl#onAudioFocusChange 메서드에 비동기적으로 전달합니다.

이 API는 오디오 제어 HAL에서 발생하는 오디오 포커스 요청의 변경사항을 모니터링하는 데도 사용할 수 있습니다. 일반적으로 HAL의 고정 오디오 포커스 요청은 활성으로 간주되며 이는 해당 활성 오디오 트랙 재생만 활성으로 간주되는 Android의 오디오 포커스 요청과 다릅니다.

AIDL 오디오 제어 HAL로 HIDL 이전

AIDL이 나오고 Android 12에서 이전이 필수가 되면서(자세한 내용은 HAL용 AIDL 참고) 오디오 제어 HAL이 AIDL로 이전되었습니다. 기존 HIDL 오디오 제어 버전 2 API의 경우 이전하려면 다음과 같이 기존 메서드를 소규모로 업데이트해야 했습니다.

interface IAudioControl {
       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   @param usage The audio usage associated with the focus change
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone that the HAL is
       *        playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred.
       */
       oneway void onAudioFocusChange(in String usage, in int zoneId,
              in AudioFocusChange focusChange);
       /**
       *   Registers focus listener to be used by HAL for requesting and
       *   abandoning audio focus.
       *   @param listener the listener interface.
       */
       oneway void registerFocusListener(in IFocusListener listener);
       /**
       *   Control the right/left balance setting of the car speakers.
       */
       oneway void setBalanceTowardRight(in float value);
       /**
       *   Control the fore/aft fade setting of the car speakers.
       */
       oneway void setFadeTowardFront(in float value);
}

해당 IFocusListener:

       interface IFocusListener {
       /**
       *   Called whenever HAL is abandoning focus as it is finished playing audio
       *   of a given usage in a specific zone.
       *
       *   @param usage The audio usage for which the HAL is abandoning focus
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone that the HAL
       *        abandoning focus
       */
       oneway void abandonAudioFocus(in String usage, in int zoneId);
       /**
       *   Called whenever HAL is requesting focus as it is starting to play audio
       *        of a given usage in a specified zone.
       *
       *   @param usage The audio usage associated with the focus request
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone where the HAL is
       *        requesting focus
       *   @param focusGain The AudioFocusChange associated with this request.
       */
       oneway void requestAudioFocus(in String usage, in int zoneId,
              in AudioFocusChange focusGain);
}

볼륨 그룹 음소거

Android 12에서는 사용자가 오디오와 상호작용하는 동안 좀 더 포괄적인 음소거 제어를 허용하기 위해 볼륨 그룹 음소거를 도입했습니다. 이 기능을 사용하면 오디오 제어 HAL이 자동차 오디오 서비스에서 가로채는 음소거 이벤트를 수신할 수 있습니다.

이 기능을 사용 설정하려면 OEM은 다음과 같이 자동차 서비스 config.xml에서 audioUseCarVolumeGroupMuting 구성을 true로 설정해야 합니다.

<!-- Configuration to enable muting of individual volume groups.
If this is set to false, muting of individual volume groups is disabled,
instead muting will toggle master mute. If this is set to true, car volume
group muting is enabled and each individual volume group can be muted separately. -->
<bool name="audioUseCarVolumeGroupMuting">true</bool>

Android 13 전에는 구성을 packages/services/Car/service/res/values/config.xml의 런타임 리소스 오버레이로 덮어써야 했습니다(자세한 내용은 리소스 오버레이로 빌드 맞춤설정 참고). Android 13부터 런타임 리소스 오버레이를 사용하여 구성 값을 변경할 수 있습니다. 자세한 내용은 런타임 시 앱 리소스 값 변경을 참고하세요.

시스템 앱은 CarAudioManager#isAudioFeatureEnabled API를 사용하여 이 기능이 사용 설정되었는지 확인할 수 있습니다. 전달된 매개변수는 CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING 상수여야 합니다. 메서드는 이 기능이 기기에서 사용 설정되어 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.

audioUseCarVolumeGroupMuting 기능을 사용 설정하는 것 외에도 AIDL 오디오 제어 HAL은 다음과 같이 볼륨 그룹 음소거 메커니즘을 구현해야 합니다.

interface IAudioControl {
       /**
       *   Notifies HAL of changes in output devices that the HAL should apply
       *   muting to.
       *
       *   This will be called in response to changes in audio mute state for each
       *   volume group and will include a {@link MutingInfo} object per audio
       *   zone that experienced a mute state event.
       *
       *   @param mutingInfos an array of {@link MutingInfo} objects for the audio
       *   zones where audio mute state has changed.
       */
       oneway void onDevicesToMuteChange(in MutingInfo[] mutingInfos);
}

여기서 음소거 정보에는 오디오 시스템의 관련 음소거 정보가 포함되어 있습니다.

parcelable MutingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be muted.
       */
       String[] deviceAddressesToMute;
       /**
       *   List of addresses for audio output devices that were previously be
       *   muted and should now be unmuted.
       */
       String[] deviceAddressesToUnmute;
}

AAOS에는 다음에 기반한 음소거 메커니즘이 두 가지 있습니다.

  • 오디오 KEYCODE_VOLUME_MUTE {:.external}을 사용하는 주요 이벤트

  • 자동차 오디오 관리자 음소거 API CarAudioManager#setVolumeGroupMute를 사용하는 자동차 오디오 서비스에 대한 직접 호출

사용 설정되면 두 메커니즘 모두 오디오 제어 HAL에 통화 음소거를 트리거합니다.

자동차 오디오 볼륨 낮추기

Android 12에서는 오디오 스트림의 동시 재생 제어를 최적화하기 위해 자동차 오디오 볼륨 낮추기를 도입했습니다. 이 기능을 사용하면 OEM이 자동차 오디오 서비스에서 결정한 자동차의 물리적 오디오 구성과 현재 재생 상태에 따라 자체 볼륨 낮추기 동작을 구현할 수 있습니다.

볼륨 낮추기 메커니즘은 오디오 포커스 스택 변경사항에 기반합니다. 포커스 변경이 발생할 때마다(포커스 요청이든 포커스 포기든) 오디오 제어 HAL에 알림이 전송됩니다. 자동차 볼륨 그룹 음소거 지원과 마찬가지로 자동차 오디오 볼륨 낮추기는 audioUseHalDuckingSignals 구성 플래그로 사용 설정할 수 있습니다.

<!-- Configuration to enable IAudioControl#onDevicesToDuckChange API to
inform HAL when to duck. If this is set to true, the API will receive signals
indicating which output devices to duck as well as what usages are currently
holding focus. If set to false, the API will not be called. -->
<bool name="audioUseHalDuckingSignals">true</bool>

이 기능을 사용 설정하려면 AIDL 오디오 제어 HAL은 자동차 오디오 서비스에서 수신한 신호를 사용하여 관련 로직을 구현해야 합니다.

interface IAudioControl {
       /**
       *   Notifies HAL of changes in output devices that the HAL should apply
       *   ducking to.
       *
       *   This will be called in response to changes in audio focus, and will
       *   include a {@link DuckingInfo} object per audio zone that experienced
       *   a change in audo focus.
       *
       *   @param duckingInfos an array of {@link DuckingInfo} objects for the
       *   audio zones where audio focus has changed.
       */
       oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos);
}

관련 오디오 시스템 정보는 오디오 볼륨 낮추기 정보에 포함되어 있습니다.

parcelable DuckingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be ducked.
       */
       String[] deviceAddressesToDuck;
       /**
       *   List of addresses for audio output devices that were previously be
       *   ducked and should now be unducked.
       */
       String[] deviceAddressesToUnduck;
       /**
       *   List of usages currently holding focus for this audio zone.
       */
       String[] usagesHoldingFocus;
}

볼륨을 낮추거나 낮추지 않을 기기 주소에 포함된 자동차 오디오 구성 정보 외에도 볼륨 낮추기 정보에는 포커스를 보유하고 있는 오디오 속성 용도에 관한 정보가 포함되어 있습니다. 이 데이터의 목적은 활성 상태인 오디오 속성 용도를 오디오 시스템에 알려주는 것입니다.

이는 자동차 오디오 구성에서 여러 오디오 속성이 단일 기기에 할당될 수 있고 추가 정보가 없으면 어떤 용도가 활성 상태인지 명확하지 않으므로 필요합니다.

AIDL 오디오 제어 HAL 2.0

API를 업데이트하고 새로운 기능의 사용을 용이하게 하기 위해 AIDL 오디오 제어 HAL이 Android 13에서 버전 2.0으로 업데이트되었습니다.

  • PlaybackTrackMetadata를 사용한 오디오 포커스
  • 오디오 게인 콜백

재생 메타데이터는 다음과 같이 android.hardware.audio.common에 정의되어 있습니다.

parcelable PlaybackTrackMetadata {
       AudioUsage usage = INVALID;
       AudioContentType contentType = UNKNOWN;
       float gain;
       AudioChannelLayout channelMask;
       AudioDevice sourceDevice;
       String[] tags;
}

AIDL 오디오 제어 버전 1.0의 다른 모든 기능은 유지되므로 사용할 수 있습니다. 예외는 오디오 포커스 변경 메서드에 설명된 대로 오디오 포커스 변경 메서드와 관련이 있습니다.

재생 트랙 메타데이터가 포함된 오디오 제어 포커스

HAL 아래 오디오 시스템에 더 많은 정보를 노출하기 위해 업데이트에서 이제 PlaybackTrackMetadata를 노출합니다. 특히 오디오 제어 HAL은 다음과 같이 새 메서드로 확장되었습니다.

interface IAudioControl {
       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   The HAL is not required to wait for a callback of AUDIOFOCUS_GAIN
       *   before playing audio, nor is it required to stop playing audio in the
       *   event of a AUDIOFOCUS_LOSS callback is received.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL is
       *    playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred.
       */
       oneway void onAudioFocusChangeWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId,
       in AudioFocusChange focusChange);
}

IFocusListener에도 유사하고 상응하는 변경이 이루어집니다.

       /**
       *   Called to indicate that the audio output stream associated with
       *   {@link android.hardware.audio.common.PlaybackTrackMetadata} is
       *   abandoning focus as playback has stopped.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       */
       oneway void abandonAudioFocusWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId);
       /**
       *   Called to indicate that the audio output stream associated with
       *   {@link android.hardware.audio.common.PlaybackTrackMetadata} has taken
       *   the focus as playback is starting for the corresponding stream.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       *   @param focusGain The focus type requested.
       */
       oneway void requestAudioFocusWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId,
       in AudioFocusChange focusGain);
}

오디오 포커스 변경 메서드

위의 포커스 작업은 HAL의 오디오 포커스 요청에 설명된 것과 동일한 방식으로 실행됩니다. 재생 트랙 메타데이터에만 오디오 속성 용도와 함께 더 많은 정보가 있습니다. 일반적으로 재생 트랙 메타데이터에서 제공하는 추가 정보가 필요하지 않으면 업데이트된 오디오 제어 HAL은 계속 이전 메서드를 사용할 수 있습니다.

HAL 개발자가 IAudioControl#onAudioFocusChangeWithMetaData를 지원하지 않기로 하면 메서드는 버전이 지정된 인터페이스 메서드 사용에 설명된 대로 UNKNOWN_TRANSACTION 오류와 함께 결과를 반환해야 합니다.

오디오 서비스는 먼저 onAudioFocusChangeWithMetaData를 호출하고 UNKNOWN_TRANSACTION 실패가 발생하면 onAudioFocusChange 메서드로 다시 시도합니다.

재생 트랙 메타데이터가 포함된 자동차 오디오 볼륨 낮추기

AIDL 오디오 제어 HAL 버전 2.0에서는 오디오 볼륨 낮추기 정보에 재생 트랙 메타데이터를 추가했습니다.

parcelable DuckingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be ducked.
       */
       String[] deviceAddressesToDuck;
       /**
       *   List of addresses for audio output devices that were previously be
       *   ducked and should now be unducked.
       */
       String[] deviceAddressesToUnduck;
       /**
       *   List of usages currently holding focus for this audio zone.
       */
       String[] usagesHoldingFocus;
       /**
       *   List of output stream metadata associated with the current focus
       *   holder for this audio zone
       */
       @nullable PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
}

usagesHoldingFocus는 지원 중단되었습니다. 이제 개발자는 playbackMetaDataHoldingFocus를 사용하여 오디오 속성 용도와 기타 오디오 정보를 결정해야 합니다. 하지만 usagesHoldingFocus 매개변수에는 여전히 이 옵션이 공식적으로 삭제될 때까지 필수 정보가 포함됩니다.

오디오 게인 콜백

HAL 아래 오디오 변경사항이 Android 13의 AAOS에 더 잘 표시되도록 하기 위해 자동차 오디오 시스템의 오디오 게인 변경사항을 자동차 오디오 서비스로 전달하는 데 사용할 수 있는 메커니즘을 추가했습니다. 이 메커니즘은 다음과 같은 게인이 변경된 각각의 이유와 함께 오디오 게인 볼륨 색인 변경사항을 노출합니다.

  • 차단되거나 음소거된 제한사항
  • 제한사항
  • 감쇠 제한사항

이러한 변경사항으로 인해 HAL 아래의 제한사항이 자동차 오디오 서비스에 노출되고 최종적으로 시스템 UI 앱에 노출되어 사용자에게 알립니다. 가능한 시스템 UI에 노출된다는 뒷부분은 시스템 UI 앱이 볼륨 그룹 정보 콜백 메커니즘을 통해 이 정보를 더 잘 가져올 수 있도록 Android 14에서 더욱 확장되었습니다.

오디오 제어 HAL API는 다음과 같이 게인 콜백을 등록합니다.

interface IAudioControl {
       /**
       *   Registers callback to be used by HAL for reporting unexpected gain(s)
       *    changed and the reason(s) why.
       *
       *   @param callback The {@link IAudioGainCallback}.
       */
       oneway void registerGainCallback(in IAudioGainCallback callback);
}

IAudioGainCallback은 다음과 같이 정의됩니다.

interface IAudioGainCallback {
       /**
       *   Used to indicate that one or more audio device port gains have changed,
       *   i.e. initiated by HAL, not by CarAudioService.
       *   This is the counter part of the
       *   {@link onDevicesToDuckChange}, {@link onDevicesToMuteChange} and,
       *   {@link setAudioDeviceGainsChanged} APIs.
       *
       *   @param reasons List of reasons that triggered the given gains changed.
       *   @param gains List of gains affected by the change.
       */
       void onAudioDeviceGainsChanged(in Reasons[] reasons,
       in AudioGainConfigInfo[] gains);
}

API 문서에 강조 표시한 대로 게인 콜백은 자동차 오디오 서비스에 의해 오디오 제어 HAL에 등록됩니다. API가 오디오 제어 HAL에서 호출되면 자동차 오디오 서비스는 상응하는 작업(예: 게인 색인 차단, 제한 또는 감쇠)으로 응답합니다.

HAL은 주로 게인 색인 상태의 변경사항을 보고하기 위해 API가 호출되는 시점을 결정합니다. 규정 요구사항에 따라 자동차의 오디오 시스템은 필요한 작업을 실행하고 사용자가 소비할 수 있도록 콜백을 사용하여 자동차 오디오 서비스에 정보를 보고해야 합니다. 예를 들어 사용자에게 UI를 표시합니다.

AIDL 오디오 제어 HAL 3.0

Android 14 AIDL 오디오 제어 HAL 버전은 더 강력한 오디오 게인 색인 기능을 제공하도록 API를 업데이트하기 위해 버전 3.0으로 업데이트되었습니다. 오디오 제어 HAL API를 통해 오디오 서비스는 다음과 같이 IModuleChangeCallback을 설정하거나 설정 해제할 수 있습니다.

interface IAudioControl {
       /**
       *   Sets callback with HAL for notifying changes to hardware module
       *   (that is: {@link android.hardware.audio.core.IModule}) configurations.
       *
       *   @param callback The {@link IModuleChangeCallback} interface to use
       *    use when new updates are available for
       */
       void setModuleChangeCallback(in IModuleChangeCallback callback);
       /**
       *   Clears module change callback
       */
       void clearModuleChangeCallback();
}

setModuleChangeCallback은 서비스가 시작될 때 또는 오류에서 복구될 때 자동차 오디오 서비스에서 등록합니다. 자동차 오디오 서비스에서 수신한 오디오 제어 HAL 바인더 종료 알림을 예로 들 수 있습니다. 오디오 제어 HAL 구현에서는 API가 호출될 때 기존 모듈 변경 콜백을 모두 대체해야 합니다.

clearModuleChangeCallback API의 경우 구현에서는 기존 콜백을 삭제하거나, 기존 콜백이 없으면 아무 작업도 하지 않아야 합니다. 오디오 제어 구현에서는 콜백의 종료 관찰자를 등록하고 온바인더 종료가 트리거되면 콜백을 삭제하는 것이 좋습니다.

IModuleChangeCallback은 다음과 같이 정의됩니다.

oneway interface IModuleChangeCallback {
       /**
       *   Used to indicate that one or more {@link AudioPort} configs have
       *   changed. Implementations MUST return at least one AudioPort.
       *
       *   @param audioPorts list of {@link AudioPort} that are updated
       */
       void onAudioPortsChanged(in AudioPort[] audioPorts);
}

모듈 변경 콜백이 자동차 오디오 서비스에 의해 등록되면 onAudioPortChanged API를 통해 오디오 포트 변경사항을 수신할 준비가 된 것입니다. API는 콜백이 등록되자마자 오디오 시스템의 볼륨 게인을 초기화하는 데 사용할 수 있습니다. 기타 동적 게인 변경사항의 경우 언제든지 API를 호출할 수 있습니다. 해당 변경사항이 적용되고 자동차 오디오 서비스가 적절하게 업데이트됩니다.