Loading core/jni/android_media_AudioSystem.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -2712,10 +2712,10 @@ static jint android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv * return AUDIO_JAVA_SUCCESS; } static jint android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jobjectArray jDeviceArray) { static jint android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jobjectArray jDeviceArray, jboolean forVolume) { const jsize maxResultSize = env->GetArrayLength(jDeviceArray); // the JNI is always expected to provide us with an array capable of holding enough // devices i.e. the most we ever route a track to. This is preferred over receiving an ArrayList Loading @@ -2734,7 +2734,7 @@ android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, AudioDeviceTypeAddrVector devices; jStatus = check_AudioSystem_Command( AudioSystem::getDevicesForAttributes(*(paa.get()), &devices)); AudioSystem::getDevicesForAttributes(*(paa.get()), &devices, forVolume)); if (jStatus != NO_ERROR) { return jStatus; } Loading Loading @@ -3045,7 +3045,7 @@ static const JNINativeMethod gMethods[] = {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I", (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset}, {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;Z)I", (void *)android_media_AudioSystem_getDevicesForAttributes}, {"setUserIdDeviceAffinities", "(I[I[Ljava/lang/String;)I", (void *)android_media_AudioSystem_setUserIdDeviceAffinities}, Loading media/java/android/media/AudioSystem.java +6 −4 Original line number Diff line number Diff line Loading @@ -1668,13 +1668,14 @@ public class AudioSystem * otherwise (typically one device, except for duplicated paths). */ public static @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { Objects.requireNonNull(attributes); final AudioDeviceAttributes[] devices = new AudioDeviceAttributes[MAX_DEVICE_ROUTING]; final int res = getDevicesForAttributes(attributes, devices); final int res = getDevicesForAttributes(attributes, devices, forVolume); final ArrayList<AudioDeviceAttributes> routeDevices = new ArrayList<>(); if (res != SUCCESS) { Log.e(TAG, "error " + res + " in getDevicesForAttributes for " + attributes); Log.e(TAG, "error " + res + " in getDevicesForAttributes attributes: " + attributes + " forVolume: " + forVolume); return routeDevices; } Loading @@ -1693,7 +1694,8 @@ public class AudioSystem private static final int MAX_DEVICE_ROUTING = 4; private static native int getDevicesForAttributes(@NonNull AudioAttributes aa, @NonNull AudioDeviceAttributes[] devices); @NonNull AudioDeviceAttributes[] devices, boolean forVolume); /** @hide returns true if master mono is enabled. */ public static native boolean getMasterMono(); Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +2 −1 Original line number Diff line number Diff line Loading @@ -396,7 +396,8 @@ import java.util.concurrent.atomic.AtomicBoolean; AudioAttributes attr = AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( AudioSystem.STREAM_VOICE_CALL); List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(attr); List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes( attr, false /* forVolume */); if (devices.isEmpty()) { if (mAudioService.isPlatformVoice()) { Log.w(TAG, Loading services/core/java/com/android/server/audio/AudioService.java +12 −6 Original line number Diff line number Diff line Loading @@ -1808,6 +1808,10 @@ public class AudioService extends IAudioService.Stub * @param caller caller of this method */ private void updateVolumeStates(int device, int streamType, String caller) { // Handle device volume aliasing of SPEAKER_SAFE. if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { device = AudioSystem.DEVICE_OUT_SPEAKER; } if (!mStreamStates[streamType].hasIndexForDevice(device)) { // set the default value, if device is affected by a full/fix/abs volume rule, it // will taken into account in checkFixedVolumeDevices() Loading @@ -1819,7 +1823,8 @@ public class AudioService extends IAudioService.Stub // Check if device to be updated is routed for the given audio stream List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build()); new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), true /* forVolume */); for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( device)) { Loading Loading @@ -2687,7 +2692,7 @@ public class AudioService extends IAudioService.Stub public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { enforceQueryStateOrModifyRoutingPermission(); return getDevicesForAttributesInt(attributes); return getDevicesForAttributesInt(attributes, false /* forVolume */); } /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) Loading @@ -2697,7 +2702,7 @@ public class AudioService extends IAudioService.Stub */ public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( @NonNull AudioAttributes attributes) { return getDevicesForAttributesInt(attributes); return getDevicesForAttributesInt(attributes, false /* forVolume */); } /** Loading @@ -2719,9 +2724,9 @@ public class AudioService extends IAudioService.Stub } protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { Objects.requireNonNull(attributes); return mAudioSystem.getDevicesForAttributes(attributes); return mAudioSystem.getDevicesForAttributes(attributes, forVolume); } /** Indicates no special treatment in the handling of the volume adjustement */ Loading Loading @@ -6490,7 +6495,8 @@ public class AudioService extends IAudioService.Stub .setUsage(AudioAttributes.USAGE_MEDIA) .build(); // calling getDevice*Int to bypass permission check final List<AudioDeviceAttributes> devices = getDevicesForAttributesInt(attributes); final List<AudioDeviceAttributes> devices = getDevicesForAttributesInt(attributes, true /* forVolume */); for (AudioDeviceAttributes device : devices) { if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { return true; Loading services/core/java/com/android/server/audio/AudioSystemAdapter.java +18 −13 Original line number Diff line number Diff line Loading @@ -24,12 +24,14 @@ import android.media.AudioSystem; import android.media.audiopolicy.AudioMix; import android.os.SystemClock; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** Loading Loading @@ -59,7 +61,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { private static final boolean USE_CACHE_FOR_GETDEVICES = true; private ConcurrentHashMap<Integer, Integer> mDevicesForStreamCache; private ConcurrentHashMap<AudioAttributes, ArrayList<AudioDeviceAttributes>> private ConcurrentHashMap<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> mDevicesForAttrCache; private int[] mMethodCacheHit; private static final Object sRoutingListenerLock = new Object(); Loading Loading @@ -201,26 +203,28 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { * @return the devices that the stream with the given attributes would be routed to */ public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { if (!ENABLE_GETDEVICES_STATS) { return getDevicesForAttributesImpl(attributes); return getDevicesForAttributesImpl(attributes, forVolume); } mMethodCallCounter[METHOD_GETDEVICESFORATTRIBUTES]++; final long startTime = SystemClock.uptimeNanos(); final ArrayList<AudioDeviceAttributes> res = getDevicesForAttributesImpl(attributes); final ArrayList<AudioDeviceAttributes> res = getDevicesForAttributesImpl( attributes, forVolume); mMethodTimeNs[METHOD_GETDEVICESFORATTRIBUTES] += SystemClock.uptimeNanos() - startTime; return res; } private @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesImpl( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { if (USE_CACHE_FOR_GETDEVICES) { ArrayList<AudioDeviceAttributes> res; final Pair<AudioAttributes, Boolean> key = new Pair(attributes, forVolume); synchronized (mDevicesForAttrCache) { res = mDevicesForAttrCache.get(attributes); res = mDevicesForAttrCache.get(key); if (res == null) { res = AudioSystem.getDevicesForAttributes(attributes); mDevicesForAttrCache.put(attributes, res); res = AudioSystem.getDevicesForAttributes(attributes, forVolume); mDevicesForAttrCache.put(key, res); if (DEBUG_CACHE) { Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES] + attrDeviceToDebugString(attributes, res)); Loading @@ -231,7 +235,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { mMethodCacheHit[METHOD_GETDEVICESFORATTRIBUTES]++; if (DEBUG_CACHE) { final ArrayList<AudioDeviceAttributes> real = AudioSystem.getDevicesForAttributes(attributes); AudioSystem.getDevicesForAttributes(attributes, forVolume); if (res.equals(real)) { Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES] + attrDeviceToDebugString(attributes, res) + " CACHE"); Loading @@ -245,7 +249,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { return res; } // not using cache return AudioSystem.getDevicesForAttributes(attributes); return AudioSystem.getDevicesForAttributes(attributes, forVolume); } private static String attrDeviceToDebugString(@NonNull AudioAttributes attr, Loading Loading @@ -523,9 +527,10 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { } pw.println(" mDevicesForAttrCache:"); if (mDevicesForAttrCache != null) { for (AudioAttributes attr : mDevicesForAttrCache.keySet()) { pw.println("\t" + attr); for (AudioDeviceAttributes devAttr : mDevicesForAttrCache.get(attr)) { for (Map.Entry<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> entry : mDevicesForAttrCache.entrySet()) { pw.println("\t" + entry.getKey().first + " forVolume: " + entry.getKey().second); for (AudioDeviceAttributes devAttr : entry.getValue()) { pw.println("\t\t" + devAttr); } } Loading Loading
core/jni/android_media_AudioSystem.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -2712,10 +2712,10 @@ static jint android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv * return AUDIO_JAVA_SUCCESS; } static jint android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jobjectArray jDeviceArray) { static jint android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jobjectArray jDeviceArray, jboolean forVolume) { const jsize maxResultSize = env->GetArrayLength(jDeviceArray); // the JNI is always expected to provide us with an array capable of holding enough // devices i.e. the most we ever route a track to. This is preferred over receiving an ArrayList Loading @@ -2734,7 +2734,7 @@ android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, AudioDeviceTypeAddrVector devices; jStatus = check_AudioSystem_Command( AudioSystem::getDevicesForAttributes(*(paa.get()), &devices)); AudioSystem::getDevicesForAttributes(*(paa.get()), &devices, forVolume)); if (jStatus != NO_ERROR) { return jStatus; } Loading Loading @@ -3045,7 +3045,7 @@ static const JNINativeMethod gMethods[] = {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I", (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset}, {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;Z)I", (void *)android_media_AudioSystem_getDevicesForAttributes}, {"setUserIdDeviceAffinities", "(I[I[Ljava/lang/String;)I", (void *)android_media_AudioSystem_setUserIdDeviceAffinities}, Loading
media/java/android/media/AudioSystem.java +6 −4 Original line number Diff line number Diff line Loading @@ -1668,13 +1668,14 @@ public class AudioSystem * otherwise (typically one device, except for duplicated paths). */ public static @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { Objects.requireNonNull(attributes); final AudioDeviceAttributes[] devices = new AudioDeviceAttributes[MAX_DEVICE_ROUTING]; final int res = getDevicesForAttributes(attributes, devices); final int res = getDevicesForAttributes(attributes, devices, forVolume); final ArrayList<AudioDeviceAttributes> routeDevices = new ArrayList<>(); if (res != SUCCESS) { Log.e(TAG, "error " + res + " in getDevicesForAttributes for " + attributes); Log.e(TAG, "error " + res + " in getDevicesForAttributes attributes: " + attributes + " forVolume: " + forVolume); return routeDevices; } Loading @@ -1693,7 +1694,8 @@ public class AudioSystem private static final int MAX_DEVICE_ROUTING = 4; private static native int getDevicesForAttributes(@NonNull AudioAttributes aa, @NonNull AudioDeviceAttributes[] devices); @NonNull AudioDeviceAttributes[] devices, boolean forVolume); /** @hide returns true if master mono is enabled. */ public static native boolean getMasterMono(); Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +2 −1 Original line number Diff line number Diff line Loading @@ -396,7 +396,8 @@ import java.util.concurrent.atomic.AtomicBoolean; AudioAttributes attr = AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( AudioSystem.STREAM_VOICE_CALL); List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(attr); List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes( attr, false /* forVolume */); if (devices.isEmpty()) { if (mAudioService.isPlatformVoice()) { Log.w(TAG, Loading
services/core/java/com/android/server/audio/AudioService.java +12 −6 Original line number Diff line number Diff line Loading @@ -1808,6 +1808,10 @@ public class AudioService extends IAudioService.Stub * @param caller caller of this method */ private void updateVolumeStates(int device, int streamType, String caller) { // Handle device volume aliasing of SPEAKER_SAFE. if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { device = AudioSystem.DEVICE_OUT_SPEAKER; } if (!mStreamStates[streamType].hasIndexForDevice(device)) { // set the default value, if device is affected by a full/fix/abs volume rule, it // will taken into account in checkFixedVolumeDevices() Loading @@ -1819,7 +1823,8 @@ public class AudioService extends IAudioService.Stub // Check if device to be updated is routed for the given audio stream List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build()); new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), true /* forVolume */); for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( device)) { Loading Loading @@ -2687,7 +2692,7 @@ public class AudioService extends IAudioService.Stub public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { enforceQueryStateOrModifyRoutingPermission(); return getDevicesForAttributesInt(attributes); return getDevicesForAttributesInt(attributes, false /* forVolume */); } /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) Loading @@ -2697,7 +2702,7 @@ public class AudioService extends IAudioService.Stub */ public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( @NonNull AudioAttributes attributes) { return getDevicesForAttributesInt(attributes); return getDevicesForAttributesInt(attributes, false /* forVolume */); } /** Loading @@ -2719,9 +2724,9 @@ public class AudioService extends IAudioService.Stub } protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { Objects.requireNonNull(attributes); return mAudioSystem.getDevicesForAttributes(attributes); return mAudioSystem.getDevicesForAttributes(attributes, forVolume); } /** Indicates no special treatment in the handling of the volume adjustement */ Loading Loading @@ -6490,7 +6495,8 @@ public class AudioService extends IAudioService.Stub .setUsage(AudioAttributes.USAGE_MEDIA) .build(); // calling getDevice*Int to bypass permission check final List<AudioDeviceAttributes> devices = getDevicesForAttributesInt(attributes); final List<AudioDeviceAttributes> devices = getDevicesForAttributesInt(attributes, true /* forVolume */); for (AudioDeviceAttributes device : devices) { if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { return true; Loading
services/core/java/com/android/server/audio/AudioSystemAdapter.java +18 −13 Original line number Diff line number Diff line Loading @@ -24,12 +24,14 @@ import android.media.AudioSystem; import android.media.audiopolicy.AudioMix; import android.os.SystemClock; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** Loading Loading @@ -59,7 +61,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { private static final boolean USE_CACHE_FOR_GETDEVICES = true; private ConcurrentHashMap<Integer, Integer> mDevicesForStreamCache; private ConcurrentHashMap<AudioAttributes, ArrayList<AudioDeviceAttributes>> private ConcurrentHashMap<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> mDevicesForAttrCache; private int[] mMethodCacheHit; private static final Object sRoutingListenerLock = new Object(); Loading Loading @@ -201,26 +203,28 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { * @return the devices that the stream with the given attributes would be routed to */ public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { if (!ENABLE_GETDEVICES_STATS) { return getDevicesForAttributesImpl(attributes); return getDevicesForAttributesImpl(attributes, forVolume); } mMethodCallCounter[METHOD_GETDEVICESFORATTRIBUTES]++; final long startTime = SystemClock.uptimeNanos(); final ArrayList<AudioDeviceAttributes> res = getDevicesForAttributesImpl(attributes); final ArrayList<AudioDeviceAttributes> res = getDevicesForAttributesImpl( attributes, forVolume); mMethodTimeNs[METHOD_GETDEVICESFORATTRIBUTES] += SystemClock.uptimeNanos() - startTime; return res; } private @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesImpl( @NonNull AudioAttributes attributes) { @NonNull AudioAttributes attributes, boolean forVolume) { if (USE_CACHE_FOR_GETDEVICES) { ArrayList<AudioDeviceAttributes> res; final Pair<AudioAttributes, Boolean> key = new Pair(attributes, forVolume); synchronized (mDevicesForAttrCache) { res = mDevicesForAttrCache.get(attributes); res = mDevicesForAttrCache.get(key); if (res == null) { res = AudioSystem.getDevicesForAttributes(attributes); mDevicesForAttrCache.put(attributes, res); res = AudioSystem.getDevicesForAttributes(attributes, forVolume); mDevicesForAttrCache.put(key, res); if (DEBUG_CACHE) { Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES] + attrDeviceToDebugString(attributes, res)); Loading @@ -231,7 +235,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { mMethodCacheHit[METHOD_GETDEVICESFORATTRIBUTES]++; if (DEBUG_CACHE) { final ArrayList<AudioDeviceAttributes> real = AudioSystem.getDevicesForAttributes(attributes); AudioSystem.getDevicesForAttributes(attributes, forVolume); if (res.equals(real)) { Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES] + attrDeviceToDebugString(attributes, res) + " CACHE"); Loading @@ -245,7 +249,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { return res; } // not using cache return AudioSystem.getDevicesForAttributes(attributes); return AudioSystem.getDevicesForAttributes(attributes, forVolume); } private static String attrDeviceToDebugString(@NonNull AudioAttributes attr, Loading Loading @@ -523,9 +527,10 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { } pw.println(" mDevicesForAttrCache:"); if (mDevicesForAttrCache != null) { for (AudioAttributes attr : mDevicesForAttrCache.keySet()) { pw.println("\t" + attr); for (AudioDeviceAttributes devAttr : mDevicesForAttrCache.get(attr)) { for (Map.Entry<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>> entry : mDevicesForAttrCache.entrySet()) { pw.println("\t" + entry.getKey().first + " forVolume: " + entry.getKey().second); for (AudioDeviceAttributes devAttr : entry.getValue()) { pw.println("\t\t" + devAttr); } } Loading