1 /* 2 * Copyright (C) 2023 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.server.hdmi; 18 19 import static android.media.AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener; 20 import static android.media.AudioDeviceVolumeManager.OnDeviceVolumeBehaviorChangedListener; 21 22 import android.annotation.CallbackExecutor; 23 import android.annotation.NonNull; 24 import android.media.AudioAttributes; 25 import android.media.AudioDeviceAttributes; 26 import android.media.AudioManager; 27 import android.media.AudioSystem; 28 import android.media.VolumeInfo; 29 30 import java.util.Collections; 31 import java.util.HashMap; 32 import java.util.HashSet; 33 import java.util.List; 34 import java.util.Map; 35 import java.util.Set; 36 import java.util.concurrent.Executor; 37 38 /** 39 * Contains a fake AudioManager and fake AudioDeviceVolumeManager. 40 * Stores the shared state for these managers, simulating a fake AudioService. 41 */ 42 public class FakeAudioFramework { 43 44 private final FakeAudioManagerWrapper mAudioManager = new FakeAudioManagerWrapper(); 45 private final FakeAudioDeviceVolumeManagerWrapper mAudioDeviceVolumeManager = 46 new FakeAudioDeviceVolumeManagerWrapper(); 47 48 private static final int DEFAULT_DEVICE_VOLUME_BEHAVIOR = 49 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 50 private final Map<AudioDeviceAttributes, Integer> mDeviceVolumeBehaviors = new HashMap<>(); 51 52 private final Set<OnDeviceVolumeBehaviorChangedListener> mVolumeBehaviorListeners = 53 new HashSet<>(); 54 55 private final Map<AudioAttributes, List<AudioDeviceAttributes>> mDevicesForAttributes = 56 new HashMap<>(); 57 58 private static final int DEFAULT_VOLUME = 0; 59 private final Map<Integer, Integer> mStreamVolumes = new HashMap<>(); 60 61 private static final int DEFAULT_MAX_VOLUME = 100; 62 private final Map<Integer, Integer> mStreamMaxVolumes = new HashMap<>(); 63 64 private static final boolean DEFAULT_MUTE_STATUS = false; 65 private final Map<Integer, Boolean> mStreamMuteStatuses = new HashMap<>(); 66 FakeAudioFramework()67 public FakeAudioFramework() { 68 } 69 70 /** 71 * Returns a fake AudioManager whose methods affect this object's internal state. 72 */ getAudioManager()73 public FakeAudioManagerWrapper getAudioManager() { 74 return mAudioManager; 75 } 76 77 public class FakeAudioManagerWrapper implements AudioManagerWrapper { 78 @Override adjustStreamVolume(int streamType, int direction, @AudioManager.PublicVolumeFlags int flags)79 public void adjustStreamVolume(int streamType, int direction, 80 @AudioManager.PublicVolumeFlags int flags) { 81 switch (direction) { 82 case AudioManager.ADJUST_MUTE: 83 mStreamMuteStatuses.put(streamType, true); 84 break; 85 case AudioManager.ADJUST_UNMUTE: 86 mStreamMuteStatuses.put(streamType, false); 87 break; 88 default: 89 // Other adjustments not implemented 90 } 91 } 92 93 @Override setStreamVolume(int streamType, int index, @AudioManager.PublicVolumeFlags int flags)94 public void setStreamVolume(int streamType, int index, 95 @AudioManager.PublicVolumeFlags int flags) { 96 mStreamVolumes.put(streamType, index); 97 } 98 99 @Override getStreamVolume(int streamType)100 public int getStreamVolume(int streamType) { 101 return mStreamVolumes.getOrDefault(streamType, DEFAULT_VOLUME); 102 } 103 104 @Override getStreamMinVolume(int streamType)105 public int getStreamMinVolume(int streamType) { 106 return 0; 107 } 108 109 @Override getStreamMaxVolume(int streamType)110 public int getStreamMaxVolume(int streamType) { 111 return mStreamMaxVolumes.getOrDefault(streamType, DEFAULT_MAX_VOLUME); 112 } 113 114 @Override isStreamMute(int streamType)115 public boolean isStreamMute(int streamType) { 116 return mStreamMuteStatuses.getOrDefault(streamType, DEFAULT_MUTE_STATUS); 117 } 118 119 @Override setStreamMute(int streamType, boolean state)120 public void setStreamMute(int streamType, boolean state) { 121 mStreamMuteStatuses.put(streamType, state); 122 } 123 124 @Override setHdmiSystemAudioSupported(boolean on)125 public int setHdmiSystemAudioSupported(boolean on) { 126 return AudioSystem.DEVICE_NONE; 127 } 128 129 @Override setWiredDeviceConnectionState(AudioDeviceAttributes attributes, int state)130 public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes, int state) { 131 // Do nothing 132 } 133 134 @Override setWiredDeviceConnectionState(int device, int state, String address, String name)135 public void setWiredDeviceConnectionState(int device, int state, String address, 136 String name) { 137 // Do nothing 138 } 139 140 141 @Override 142 @AudioManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)143 public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 144 return mDeviceVolumeBehaviors.getOrDefault(device, DEFAULT_DEVICE_VOLUME_BEHAVIOR); 145 } 146 setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)147 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 148 @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 149 setVolumeBehaviorHelper(device, deviceVolumeBehavior); 150 } 151 152 @Override 153 @NonNull getDevicesForAttributes( @onNull AudioAttributes attributes)154 public List<AudioDeviceAttributes> getDevicesForAttributes( 155 @NonNull AudioAttributes attributes) { 156 return mDevicesForAttributes.getOrDefault(attributes, Collections.emptyList()); 157 } 158 } 159 160 /** 161 * Returns a fake AudioDeviceVolumeManager whose methods affect this object's internal state. 162 */ getAudioDeviceVolumeManager()163 public FakeAudioDeviceVolumeManagerWrapper getAudioDeviceVolumeManager() { 164 return mAudioDeviceVolumeManager; 165 } 166 167 public class FakeAudioDeviceVolumeManagerWrapper implements AudioDeviceVolumeManagerWrapper { 168 @Override addOnDeviceVolumeBehaviorChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnDeviceVolumeBehaviorChangedListener listener)169 public void addOnDeviceVolumeBehaviorChangedListener( 170 @NonNull @CallbackExecutor Executor executor, 171 @NonNull OnDeviceVolumeBehaviorChangedListener listener) 172 throws SecurityException { 173 mVolumeBehaviorListeners.add(listener); 174 } 175 176 @Override removeOnDeviceVolumeBehaviorChangedListener( @onNull OnDeviceVolumeBehaviorChangedListener listener)177 public void removeOnDeviceVolumeBehaviorChangedListener( 178 @NonNull OnDeviceVolumeBehaviorChangedListener listener) { 179 mVolumeBehaviorListeners.remove(listener); 180 } 181 182 @Override setDeviceAbsoluteVolumeBehavior( @onNull AudioDeviceAttributes device, @NonNull VolumeInfo volume, @NonNull @CallbackExecutor Executor executor, @NonNull OnAudioDeviceVolumeChangedListener vclistener, boolean handlesVolumeAdjustment)183 public void setDeviceAbsoluteVolumeBehavior( 184 @NonNull AudioDeviceAttributes device, 185 @NonNull VolumeInfo volume, 186 @NonNull @CallbackExecutor Executor executor, 187 @NonNull OnAudioDeviceVolumeChangedListener vclistener, 188 boolean handlesVolumeAdjustment) { 189 setVolumeBehaviorHelper(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 190 } 191 192 @Override setDeviceAbsoluteVolumeAdjustOnlyBehavior( @onNull AudioDeviceAttributes device, @NonNull VolumeInfo volume, @NonNull @CallbackExecutor Executor executor, @NonNull OnAudioDeviceVolumeChangedListener vclistener, boolean handlesVolumeAdjustment)193 public void setDeviceAbsoluteVolumeAdjustOnlyBehavior( 194 @NonNull AudioDeviceAttributes device, 195 @NonNull VolumeInfo volume, 196 @NonNull @CallbackExecutor Executor executor, 197 @NonNull OnAudioDeviceVolumeChangedListener vclistener, 198 boolean handlesVolumeAdjustment) { 199 setVolumeBehaviorHelper(device, 200 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY); 201 } 202 } 203 204 /** 205 * Allows tests to manipulate the return value of 206 * {@link FakeAudioManagerWrapper#getDevicesForAttributes} 207 */ setDevicesForAttributes(AudioAttributes attributes, List<AudioDeviceAttributes> devices)208 public void setDevicesForAttributes(AudioAttributes attributes, 209 List<AudioDeviceAttributes> devices) { 210 mDevicesForAttributes.put(attributes, devices); 211 } 212 213 /** 214 * Allows tests to manipulate the return value of 215 * {@link FakeAudioManagerWrapper#getStreamMaxVolume} 216 */ setStreamMaxVolume(int streamType, int maxVolume)217 public void setStreamMaxVolume(int streamType, int maxVolume) { 218 mStreamMaxVolumes.put(streamType, maxVolume); 219 } 220 221 /** 222 * Helper method for changing an audio device's volume behavior. Notifies listeners. 223 */ setVolumeBehaviorHelper(AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int newVolumeBehavior)224 private void setVolumeBehaviorHelper(AudioDeviceAttributes device, 225 @AudioManager.DeviceVolumeBehavior int newVolumeBehavior) { 226 227 int currentVolumeBehavior = mDeviceVolumeBehaviors.getOrDefault( 228 device, DEFAULT_DEVICE_VOLUME_BEHAVIOR); 229 230 mDeviceVolumeBehaviors.put(device, newVolumeBehavior); 231 232 if (newVolumeBehavior != currentVolumeBehavior) { 233 // Notify volume behavior listeners 234 for (OnDeviceVolumeBehaviorChangedListener listener : mVolumeBehaviorListeners) { 235 listener.onDeviceVolumeBehaviorChanged(device, newVolumeBehavior); 236 } 237 } 238 } 239 } 240