AudioService: update getDevicesForAttributes
Add forVolume parameter to account for volume handling. Test: volume changes, adb shell dumpsys audio Bug: 219974551 Merged-In: I1b6b4a9d3c52bd4375ee3ce2f50fd9a0e47f6a90 Change-Id: I1b6b4a9d3c52bd4375ee3ce2f50fd9a0e47f6a90
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
@@ -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)) {
|
||||
@@ -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)
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -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();
|
||||
@@ -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));
|
||||
@@ -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");
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +264,8 @@ public class SpatializerHelper {
|
||||
return;
|
||||
}
|
||||
mState = STATE_DISABLED_UNAVAILABLE;
|
||||
mASA.getDevicesForAttributes(DEFAULT_ATTRIBUTES).toArray(ROUTING_DEVICES);
|
||||
mASA.getDevicesForAttributes(
|
||||
DEFAULT_ATTRIBUTES, false /* forVolume */).toArray(ROUTING_DEVICES);
|
||||
// note at this point mSpat is still not instantiated
|
||||
}
|
||||
|
||||
@@ -298,7 +299,8 @@ public class SpatializerHelper {
|
||||
case STATE_DISABLED_AVAILABLE:
|
||||
break;
|
||||
}
|
||||
mASA.getDevicesForAttributes(DEFAULT_ATTRIBUTES).toArray(ROUTING_DEVICES);
|
||||
mASA.getDevicesForAttributes(
|
||||
DEFAULT_ATTRIBUTES, false /* forVolume */).toArray(ROUTING_DEVICES);
|
||||
|
||||
// is media routed to a new device?
|
||||
if (isWireless(ROUTING_DEVICES[0].getType())) {
|
||||
@@ -865,7 +867,8 @@ public class SpatializerHelper {
|
||||
}
|
||||
AudioDeviceAttributes[] devices = new AudioDeviceAttributes[1];
|
||||
// going through adapter to take advantage of routing cache
|
||||
mASA.getDevicesForAttributes(attributes).toArray(devices);
|
||||
mASA.getDevicesForAttributes(
|
||||
attributes, false /* forVolume */).toArray(devices);
|
||||
final boolean able = canBeSpatializedOnDevice(attributes, format, devices);
|
||||
logd("canBeSpatialized returning " + able);
|
||||
return able;
|
||||
|
||||
Reference in New Issue
Block a user