1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.audio; 18 19 import static android.car.builtin.media.AudioManagerHelper.addTagToAudioAttributes; 20 import static android.car.builtin.media.AudioManagerHelper.getTags; 21 import static android.car.builtin.media.AudioManagerHelper.usageToXsdString; 22 23 import android.hardware.audio.common.PlaybackTrackMetadata; 24 import android.hardware.automotive.audiocontrol.DuckingInfo; 25 import android.media.AudioAttributes; 26 import android.media.audio.common.AudioChannelLayout; 27 import android.media.audio.common.AudioDevice; 28 import android.media.audio.common.AudioDeviceAddress; 29 import android.media.audio.common.AudioDeviceDescription; 30 31 import com.android.car.audio.CarAudioContext.AudioAttributesWrapper; 32 import com.android.car.internal.annotation.AttributeUsage; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.Objects; 37 import java.util.Set; 38 39 /** Car HAL audio Utils */ 40 public final class CarHalAudioUtils { CarHalAudioUtils()41 private CarHalAudioUtils() {} 42 43 /** 44 * Creates {@link DuckingInfo} instance from contents of {@link CarDuckingInfo}. 45 * 46 * <p>Converts usages to XSD strings as part of this process. 47 */ generateDuckingInfo(CarDuckingInfo carDuckingInfo)48 public static DuckingInfo generateDuckingInfo(CarDuckingInfo carDuckingInfo) { 49 Objects.requireNonNull(carDuckingInfo, "Car Ducking Info can not be null"); 50 DuckingInfo duckingInfo = new DuckingInfo(); 51 duckingInfo.zoneId = carDuckingInfo.getZoneId(); 52 duckingInfo.deviceAddressesToDuck = 53 carDuckingInfo.getAddressesToDuck().toArray(new String[0]); 54 duckingInfo.deviceAddressesToUnduck = 55 carDuckingInfo.getAddressesToUnduck().toArray(new String[0]); 56 List<PlaybackTrackMetadata> playbackTrackMetadataList = 57 carDuckingInfo.getPlaybackMetaDataHoldingFocus(); 58 duckingInfo.playbackMetaDataHoldingFocus = 59 playbackTrackMetadataList.toArray(PlaybackTrackMetadata[]::new); 60 duckingInfo.usagesHoldingFocus = metadatasToUsageStrings(playbackTrackMetadataList); 61 return duckingInfo; 62 } 63 64 /** 65 * Converts the {@link AttributeUsage} into a metadata for a particular 66 * audio zone. 67 * 68 */ audioAttributeToMetadata( AudioAttributes audioAttributes, CarAudioZone zone)69 public static PlaybackTrackMetadata audioAttributeToMetadata( 70 AudioAttributes audioAttributes, CarAudioZone zone) { 71 Objects.requireNonNull(zone, "Car audio zone can not be null"); 72 int carAudioContextId = zone.getCarAudioContext() 73 .getContextForAudioAttribute(audioAttributes); 74 String address = zone.getAddressForContext(carAudioContextId); 75 return audioAttributeToMetadata(audioAttributes, address); 76 } 77 audioAttributeToMetadata(AudioAttributes audioAttributes)78 public static PlaybackTrackMetadata audioAttributeToMetadata(AudioAttributes audioAttributes) { 79 return audioAttributeToMetadata(audioAttributes, /* deviceAddress= */ ""); 80 } 81 audioAttributeToMetadata( AudioAttributes audioAttributes, String deviceAddress)82 private static PlaybackTrackMetadata audioAttributeToMetadata( 83 AudioAttributes audioAttributes, String deviceAddress) { 84 Objects.requireNonNull(audioAttributes, "Audio Attributes can not be null"); 85 Objects.requireNonNull(deviceAddress, "Device Address can not be null"); 86 87 PlaybackTrackMetadata playbackTrackMetadata = new PlaybackTrackMetadata(); 88 playbackTrackMetadata.usage = audioAttributes.getSystemUsage(); 89 playbackTrackMetadata.contentType = audioAttributes.getContentType(); 90 Set<String> tags = getTags(audioAttributes); 91 String[] tagsArray = new String[tags.size()]; 92 playbackTrackMetadata.tags = tags.toArray(tagsArray); 93 playbackTrackMetadata.channelMask = AudioChannelLayout.none(0); 94 AudioDeviceDescription audioDeviceDescription = new AudioDeviceDescription(); 95 audioDeviceDescription.connection = ""; 96 AudioDevice audioDevice = new AudioDevice(); 97 audioDevice.type = audioDeviceDescription; 98 audioDevice.address = AudioDeviceAddress.id(deviceAddress); 99 playbackTrackMetadata.sourceDevice = audioDevice; 100 return playbackTrackMetadata; 101 } 102 usageToMetadata( @ttributeUsage int usage, CarAudioZone zone)103 public static PlaybackTrackMetadata usageToMetadata( 104 @AttributeUsage int usage, CarAudioZone zone) { 105 Objects.requireNonNull(zone, "Car audio zone can not be null"); 106 AudioAttributes attributes = CarAudioContext.getAudioAttributeFromUsage(usage); 107 return audioAttributeToMetadata(attributes, zone); 108 } 109 usageToMetadata(@ttributeUsage int usage)110 public static PlaybackTrackMetadata usageToMetadata(@AttributeUsage int usage) { 111 AudioAttributes attributes = CarAudioContext.getAudioAttributeFromUsage(usage); 112 return audioAttributeToMetadata(attributes); 113 } 114 audioAttributesWrapperToMetadata( AudioAttributesWrapper audioAttributesWrapper)115 public static PlaybackTrackMetadata audioAttributesWrapperToMetadata( 116 AudioAttributesWrapper audioAttributesWrapper) { 117 Objects.requireNonNull(audioAttributesWrapper, "Audio Attributes Wrapper can not be null"); 118 return audioAttributeToMetadata(audioAttributesWrapper.getAudioAttributes()); 119 } 120 121 /** 122 * Converts the list of {@link AttributeUsage} usages into 123 * Playback metadata for a particular zone. 124 * 125 */ audioAttributesToMetadatas( List<AudioAttributes> audioAttributes, CarAudioZone zone)126 public static List<PlaybackTrackMetadata> audioAttributesToMetadatas( 127 List<AudioAttributes> audioAttributes, CarAudioZone zone) { 128 Objects.requireNonNull(zone, "Car audio zone can not be null"); 129 List<PlaybackTrackMetadata> playbackTrackMetadataList = 130 new ArrayList<>(audioAttributes.size()); 131 for (int index = 0; index < audioAttributes.size(); index++) { 132 playbackTrackMetadataList.add(audioAttributeToMetadata(audioAttributes.get(index), 133 zone)); 134 } 135 return playbackTrackMetadataList; 136 } 137 audioAttributesToMetadatas( List<AudioAttributes> audioAttributes)138 public static List<PlaybackTrackMetadata> audioAttributesToMetadatas( 139 List<AudioAttributes> audioAttributes) { 140 List<PlaybackTrackMetadata> metadataList = new ArrayList<>(audioAttributes.size()); 141 for (int index = 0; index < audioAttributes.size(); index++) { 142 metadataList.add(audioAttributeToMetadata(audioAttributes.get(index))); 143 } 144 return metadataList; 145 } 146 147 /** 148 * Converts a playback track metadata into the corresponding audio attribute 149 * 150 */ metadataToAudioAttribute(PlaybackTrackMetadata metadata)151 public static AudioAttributes metadataToAudioAttribute(PlaybackTrackMetadata metadata) { 152 AudioAttributes.Builder builder = new AudioAttributes.Builder(); 153 if (AudioAttributes.isSystemUsage(metadata.usage)) { 154 builder.setSystemUsage(metadata.usage); 155 } else { 156 builder.setUsage(metadata.usage); 157 } 158 builder.setContentType(metadata.contentType); 159 if (metadata.tags != null) { 160 for (int i = 0; i < metadata.tags.length; i++) { 161 addTagToAudioAttributes(builder, metadata.tags[i]); 162 } 163 } 164 return builder.build(); 165 } 166 167 /** 168 * Converts a list playback track metadata into list of audio attributes 169 * 170 */ metadataToAudioAttributes( List<PlaybackTrackMetadata> playbackTrackMetadataList)171 public static List<AudioAttributes> metadataToAudioAttributes( 172 List<PlaybackTrackMetadata> playbackTrackMetadataList) { 173 List<AudioAttributes> audioAttributesForMetadata = 174 new ArrayList<>(playbackTrackMetadataList.size()); 175 for (int index = 0; index < playbackTrackMetadataList.size(); index++) { 176 audioAttributesForMetadata.add( 177 metadataToAudioAttribute(playbackTrackMetadataList.get(index))); 178 } 179 return audioAttributesForMetadata; 180 } 181 182 /** 183 * Converts a list of playback track metadata into an array of 184 * audio usages in string representation. 185 */ metadatasToUsageStrings( List<PlaybackTrackMetadata> playbackTrackMetadataList)186 public static String[] metadatasToUsageStrings( 187 List<PlaybackTrackMetadata> playbackTrackMetadataList) { 188 String[] usageLiteralsForMetadata = new String[playbackTrackMetadataList.size()]; 189 for (int index = 0; index < playbackTrackMetadataList.size(); index++) { 190 PlaybackTrackMetadata playbackTrackMetadata = playbackTrackMetadataList.get(index); 191 usageLiteralsForMetadata[index] = usageToXsdString(playbackTrackMetadata.usage); 192 } 193 return usageLiteralsForMetadata; 194 } 195 } 196