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 package com.android.car.audio; 17 18 import android.util.SparseArray; 19 20 import com.android.car.audio.CarAudioContext.AudioContext; 21 import com.android.internal.annotations.VisibleForTesting; 22 import com.android.internal.util.Preconditions; 23 24 import java.util.List; 25 import java.util.Objects; 26 27 final class CarVolumeGroupFactory { 28 private static final int UNSET_STEP_SIZE = -1; 29 30 private final String mName; 31 private final int mId; 32 private final int mZoneId; 33 private final int mConfigId; 34 private final boolean mUseCarVolumeGroupMute; 35 private final CarAudioSettings mCarAudioSettings; 36 private final SparseArray<CarAudioDeviceInfo> mContextToDeviceInfo = new SparseArray<>(); 37 private final CarAudioContext mCarAudioContext; 38 private final AudioManagerWrapper mAudioManager; 39 private final CarActivationVolumeConfig mCarActivationVolumeConfig; 40 41 private int mStepSize = UNSET_STEP_SIZE; 42 private int mDefaultGain = Integer.MIN_VALUE; 43 private int mMaxGain = Integer.MIN_VALUE; 44 private int mMinGain = Integer.MAX_VALUE; 45 CarVolumeGroupFactory(AudioManagerWrapper audioManager, CarAudioSettings carAudioSettings, CarAudioContext carAudioContext, int zoneId, int configId, int volumeGroupId, String name, boolean useCarVolumeGroupMute, CarActivationVolumeConfig carActivationVolumeConfig)46 CarVolumeGroupFactory(AudioManagerWrapper audioManager, CarAudioSettings carAudioSettings, 47 CarAudioContext carAudioContext, int zoneId, int configId, int volumeGroupId, 48 String name, boolean useCarVolumeGroupMute, 49 CarActivationVolumeConfig carActivationVolumeConfig) { 50 mAudioManager = audioManager; 51 mCarAudioSettings = Objects.requireNonNull(carAudioSettings, 52 "Car audio settings can not be null"); 53 mCarAudioContext = Objects.requireNonNull(carAudioContext, 54 "Car audio context can not be null"); 55 mZoneId = zoneId; 56 mConfigId = configId; 57 mId = volumeGroupId; 58 mName = Objects.requireNonNull(name, "Car Volume Group name can not be null"); 59 mUseCarVolumeGroupMute = useCarVolumeGroupMute; 60 mCarActivationVolumeConfig = Objects.requireNonNull(carActivationVolumeConfig, 61 "Car activation volume config can not be null"); 62 } 63 getCarVolumeGroup(boolean useCoreAudioVolume)64 CarVolumeGroup getCarVolumeGroup(boolean useCoreAudioVolume) { 65 Preconditions.checkArgument(mContextToDeviceInfo.size() != 0, 66 "setDeviceInfoForContext has to be called at least once before building"); 67 CarVolumeGroup group; 68 if (useCoreAudioVolume) { 69 group = new CoreAudioVolumeGroup(mAudioManager, mCarAudioContext, mCarAudioSettings, 70 mContextToDeviceInfo, mZoneId, mConfigId, mId, mName, mUseCarVolumeGroupMute, 71 mCarActivationVolumeConfig); 72 } else { 73 group = new CarAudioVolumeGroup(mCarAudioContext, mCarAudioSettings, 74 mContextToDeviceInfo, mZoneId, mConfigId, mId, mName, mStepSize, mDefaultGain, 75 mMinGain, mMaxGain, mUseCarVolumeGroupMute, mCarActivationVolumeConfig); 76 } 77 group.init(); 78 return group; 79 } 80 setDeviceInfoForContext(int carAudioContextId, CarAudioDeviceInfo info)81 void setDeviceInfoForContext(int carAudioContextId, CarAudioDeviceInfo info) { 82 Preconditions.checkArgument(mContextToDeviceInfo.get(carAudioContextId) == null, 83 "Context %s has already been set to %s", 84 mCarAudioContext.toString(carAudioContextId), 85 mContextToDeviceInfo.get(carAudioContextId)); 86 87 if (mContextToDeviceInfo.size() == 0) { 88 mStepSize = info.getStepValue(); 89 } else { 90 Preconditions.checkArgument( 91 info.getStepValue() == mStepSize, 92 "Gain controls within one group must have same step value"); 93 } 94 95 mContextToDeviceInfo.put(carAudioContextId, info); 96 97 // TODO(b/271749259) - this logic is redundant now. clean up 98 if (info.getDefaultGain() > mDefaultGain) { 99 // We're arbitrarily selecting the highest 100 // device default gain as the group's default. 101 mDefaultGain = info.getDefaultGain(); 102 } 103 if (info.getMaxGain() > mMaxGain) { 104 mMaxGain = info.getMaxGain(); 105 } 106 if (info.getMinGain() < mMinGain) { 107 mMinGain = info.getMinGain(); 108 } 109 } 110 setNonLegacyContexts(CarAudioDeviceInfo info)111 void setNonLegacyContexts(CarAudioDeviceInfo info) { 112 List<Integer> nonLegacyCarSystemContexts = CarAudioContext.getCarSystemContextIds(); 113 for (int index = 0; index < nonLegacyCarSystemContexts.size(); index++) { 114 @AudioContext int audioContext = nonLegacyCarSystemContexts.get(index); 115 setDeviceInfoForContext(audioContext, info); 116 } 117 } 118 119 @VisibleForTesting getMinGain()120 int getMinGain() { 121 return mMinGain; 122 } 123 124 @VisibleForTesting getMaxGain()125 int getMaxGain() { 126 return mMaxGain; 127 } 128 129 @VisibleForTesting getDefaultGain()130 int getDefaultGain() { 131 return mDefaultGain; 132 } 133 } 134