1 /* 2 * Copyright (C) 2021 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.media.CarVolumeGroupEvent.EVENT_TYPE_VOLUME_GAIN_INDEX_CHANGED; 20 21 import static com.android.car.audio.GainBuilder.DEFAULT_GAIN; 22 import static com.android.car.audio.GainBuilder.MAX_GAIN; 23 import static com.android.car.audio.GainBuilder.STEP_SIZE; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.when; 29 30 import android.car.media.CarVolumeGroupInfo; 31 import android.util.ArrayMap; 32 import android.util.SparseArray; 33 34 import com.google.common.collect.ImmutableList; 35 36 import java.util.ArrayList; 37 import java.util.List; 38 import java.util.Map; 39 40 /** 41 * Class to build mock volume group 42 */ 43 public final class VolumeGroupBuilder { 44 45 private SparseArray<String> mDeviceAddresses = new SparseArray<>(); 46 private CarAudioDeviceInfo mCarAudioDeviceInfoMock; 47 private ArrayMap<String, List<Integer>> mUsagesDeviceAddresses = new ArrayMap<>(); 48 private String mName; 49 private boolean mIsMuted; 50 private int mZoneId; 51 private int mId; 52 53 /** 54 * Add name for volume group 55 */ setName(String name)56 public VolumeGroupBuilder setName(String name) { 57 mName = name; 58 return this; 59 } 60 61 /** 62 * Add devices address for context 63 */ addDeviceAddressAndContexts(@arAudioContext.AudioContext int context, String address)64 public VolumeGroupBuilder addDeviceAddressAndContexts(@CarAudioContext.AudioContext int context, 65 String address) { 66 mDeviceAddresses.put(context, address); 67 return this; 68 } 69 70 /** 71 * Set devices address with usage 72 */ addDeviceAddressAndUsages(int usage, String address)73 public VolumeGroupBuilder addDeviceAddressAndUsages(int usage, String address) { 74 if (!mUsagesDeviceAddresses.containsKey(address)) { 75 mUsagesDeviceAddresses.put(address, new ArrayList<>()); 76 } 77 mUsagesDeviceAddresses.get(address).add(usage); 78 return this; 79 } 80 81 /** 82 * Add mocked car audio device info 83 */ addCarAudioDeviceInfoMock(CarAudioDeviceInfo infoMock)84 public VolumeGroupBuilder addCarAudioDeviceInfoMock(CarAudioDeviceInfo infoMock) { 85 mCarAudioDeviceInfoMock = infoMock; 86 return this; 87 } 88 89 /** 90 * Sets volume group is muted 91 */ setIsMuted(boolean isMuted)92 public VolumeGroupBuilder setIsMuted(boolean isMuted) { 93 mIsMuted = isMuted; 94 return this; 95 } 96 setZoneId(int zoneId)97 public VolumeGroupBuilder setZoneId(int zoneId) { 98 mZoneId = zoneId; 99 return this; 100 } 101 setGroupId(int groupId)102 public VolumeGroupBuilder setGroupId(int groupId) { 103 mId = groupId; 104 return this; 105 } 106 107 /** 108 * Builds car volume group 109 */ build()110 public CarVolumeGroup build() { 111 CarVolumeGroup carVolumeGroup = mock(CarVolumeGroup.class); 112 Map<String, ArrayList<Integer>> addressToContexts = new ArrayMap<>(); 113 @CarAudioContext.AudioContext int[] contexts = new int[mDeviceAddresses.size()]; 114 115 for (int index = 0; index < mDeviceAddresses.size(); index++) { 116 @CarAudioContext.AudioContext int context = mDeviceAddresses.keyAt(index); 117 String address = mDeviceAddresses.get(context); 118 when(carVolumeGroup.getAddressForContext(context)).thenReturn(address); 119 if (!addressToContexts.containsKey(address)) { 120 addressToContexts.put(address, new ArrayList<>()); 121 } 122 addressToContexts.get(address).add(context); 123 contexts[index] = context; 124 } 125 126 for (int index = 0; index < mUsagesDeviceAddresses.size(); index++) { 127 String address = mUsagesDeviceAddresses.keyAt(index); 128 List<Integer> usagesForAddress = mUsagesDeviceAddresses.get(address); 129 when(carVolumeGroup.getAllSupportedUsagesForAddress(eq(address))) 130 .thenReturn(usagesForAddress); 131 } 132 133 when(carVolumeGroup.getContexts()).thenReturn(contexts); 134 135 for (String address : addressToContexts.keySet()) { 136 when(carVolumeGroup.getContextsForAddress(address)) 137 .thenReturn(ImmutableList.copyOf(addressToContexts.get(address))); 138 } 139 when(carVolumeGroup.getAddresses()) 140 .thenReturn(ImmutableList.copyOf(addressToContexts.keySet())); 141 142 when(carVolumeGroup.getCarAudioDeviceInfoForAddress(any())) 143 .thenReturn(mCarAudioDeviceInfoMock); 144 145 if (mName != null) { 146 when(carVolumeGroup.getName()).thenReturn(mName); 147 } 148 when(carVolumeGroup.isMuted()).thenReturn(mIsMuted); 149 150 when(carVolumeGroup.getId()).thenReturn(mId); 151 152 when(carVolumeGroup.getCarVolumeGroupInfo()).thenReturn(new CarVolumeGroupInfo.Builder( 153 "Name: " + mName, mZoneId, mId).setMinVolumeGainIndex(0) 154 .setMaxVolumeGainIndex(MAX_GAIN / STEP_SIZE) 155 .setVolumeGainIndex(DEFAULT_GAIN / STEP_SIZE).build()); 156 157 when(carVolumeGroup.calculateNewGainStageFromDeviceInfos()) 158 .thenReturn(EVENT_TYPE_VOLUME_GAIN_INDEX_CHANGED); 159 160 return carVolumeGroup; 161 } 162 } 163