Merge "AudioEffect: add isEffectSupportedForDevice() API" into rvc-dev

This commit is contained in:
Eric Laurent
2020-03-19 17:57:50 +00:00
committed by Android (Google) Code Review
3 changed files with 51 additions and 9 deletions

View File

@@ -4391,6 +4391,7 @@ package android.media.audiofx {
public class AudioEffect { public class AudioEffect {
ctor @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public AudioEffect(@NonNull java.util.UUID, @NonNull android.media.AudioDeviceAttributes); ctor @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public AudioEffect(@NonNull java.util.UUID, @NonNull android.media.AudioDeviceAttributes);
method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static boolean isEffectSupportedForDevice(@NonNull java.util.UUID, @NonNull android.media.AudioDeviceAttributes);
} }
} }

View File

@@ -477,13 +477,21 @@ public class AudioEffect {
@SystemApi @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
public AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAttributes device) { public AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAttributes device) {
this(EFFECT_TYPE_NULL, Objects.requireNonNull(uuid), 0, -2, Objects.requireNonNull(device)); this(EFFECT_TYPE_NULL, Objects.requireNonNull(uuid),
0, -2, Objects.requireNonNull(device));
} }
private AudioEffect(UUID type, UUID uuid, int priority, private AudioEffect(UUID type, UUID uuid, int priority,
int audioSession, @Nullable AudioDeviceAttributes device) int audioSession, @Nullable AudioDeviceAttributes device)
throws IllegalArgumentException, UnsupportedOperationException, throws IllegalArgumentException, UnsupportedOperationException,
RuntimeException { RuntimeException {
this(type, uuid, priority, audioSession, device, false);
}
private AudioEffect(UUID type, UUID uuid, int priority,
int audioSession, @Nullable AudioDeviceAttributes device, boolean probe)
throws IllegalArgumentException, UnsupportedOperationException,
RuntimeException {
int[] id = new int[1]; int[] id = new int[1];
Descriptor[] desc = new Descriptor[1]; Descriptor[] desc = new Descriptor[1];
@@ -498,7 +506,7 @@ public class AudioEffect {
int initResult = native_setup(new WeakReference<AudioEffect>(this), int initResult = native_setup(new WeakReference<AudioEffect>(this),
type.toString(), uuid.toString(), priority, audioSession, type.toString(), uuid.toString(), priority, audioSession,
deviceType, deviceAddress, deviceType, deviceAddress,
id, desc, ActivityThread.currentOpPackageName()); id, desc, ActivityThread.currentOpPackageName(), probe);
if (initResult != SUCCESS && initResult != ALREADY_EXISTS) { if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
Log.e(TAG, "Error code " + initResult Log.e(TAG, "Error code " + initResult
+ " when initializing AudioEffect."); + " when initializing AudioEffect.");
@@ -517,8 +525,33 @@ public class AudioEffect {
} }
mId = id[0]; mId = id[0];
mDescriptor = desc[0]; mDescriptor = desc[0];
synchronized (mStateLock) { if (!probe) {
mState = STATE_INITIALIZED; synchronized (mStateLock) {
mState = STATE_INITIALIZED;
}
}
}
/**
* Checks if an AudioEffect identified by the supplied uuid can be attached
* to an audio device described by the supplied AudioDeviceAttributes.
* @param uuid unique identifier of a particular effect implementation.
* @param device the device the effect would be attached to.
* @return true if possible, false otherwise.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
public static boolean isEffectSupportedForDevice(
@NonNull UUID uuid, @NonNull AudioDeviceAttributes device) {
try {
AudioEffect fx = new AudioEffect(
EFFECT_TYPE_NULL, Objects.requireNonNull(uuid),
0, -2, Objects.requireNonNull(device), true);
fx.release();
return true;
} catch (Exception e) {
return false;
} }
} }
@@ -1340,7 +1373,7 @@ public class AudioEffect {
private native final int native_setup(Object audioeffect_this, String type, private native final int native_setup(Object audioeffect_this, String type,
String uuid, int priority, int audioSession, String uuid, int priority, int audioSession,
int deviceType, String deviceAddress, int[] id, Object[] desc, int deviceType, String deviceAddress, int[] id, Object[] desc,
String opPackageName); String opPackageName, boolean probe);
private native final void native_finalize(); private native final void native_finalize();

View File

@@ -270,7 +270,7 @@ static jint
android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jstring type, jstring uuid, jint priority, jint sessionId, jstring type, jstring uuid, jint priority, jint sessionId,
jint deviceType, jstring deviceAddress, jint deviceType, jstring deviceAddress,
jintArray jId, jobjectArray javadesc, jstring opPackageName) jintArray jId, jobjectArray javadesc, jstring opPackageName, jboolean probe)
{ {
ALOGV("android_media_AudioEffect_native_setup"); ALOGV("android_media_AudioEffect_native_setup");
AudioEffectJniStorage* lpJniStorage = NULL; AudioEffectJniStorage* lpJniStorage = NULL;
@@ -345,12 +345,14 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
&lpJniStorage->mCallbackData, &lpJniStorage->mCallbackData,
(audio_session_t) sessionId, (audio_session_t) sessionId,
AUDIO_IO_HANDLE_NONE, AUDIO_IO_HANDLE_NONE,
device); device,
probe);
if (lpAudioEffect == 0) { if (lpAudioEffect == 0) {
ALOGE("Error creating AudioEffect"); ALOGE("Error creating AudioEffect");
goto setup_failure; goto setup_failure;
} }
lStatus = AudioEffectJni::translateNativeErrorToJava(lpAudioEffect->initCheck()); lStatus = AudioEffectJni::translateNativeErrorToJava(lpAudioEffect->initCheck());
if (lStatus != AUDIOEFFECT_SUCCESS && lStatus != AUDIOEFFECT_ERROR_ALREADY_EXISTS) { if (lStatus != AUDIOEFFECT_SUCCESS && lStatus != AUDIOEFFECT_ERROR_ALREADY_EXISTS) {
ALOGE("AudioEffect initCheck failed %d", lStatus); ALOGE("AudioEffect initCheck failed %d", lStatus);
@@ -387,7 +389,13 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
env->SetObjectArrayElement(javadesc, 0, jdesc); env->SetObjectArrayElement(javadesc, 0, jdesc);
env->DeleteLocalRef(jdesc); env->DeleteLocalRef(jdesc);
setAudioEffect(env, thiz, lpAudioEffect); // In probe mode, release the native object and clear our strong reference
// to force all method calls from JAVA to be rejected.
if (probe) {
setAudioEffect(env, thiz, 0);
} else {
setAudioEffect(env, thiz, lpAudioEffect);
}
env->SetLongField(thiz, fields.fidJniData, (jlong)lpJniStorage); env->SetLongField(thiz, fields.fidJniData, (jlong)lpJniStorage);
@@ -766,7 +774,7 @@ android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz _
// Dalvik VM type signatures // Dalvik VM type signatures
static const JNINativeMethod gMethods[] = { static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)android_media_AudioEffect_native_init}, {"native_init", "()V", (void *)android_media_AudioEffect_native_init},
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Ljava/lang/String;)I", {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Ljava/lang/String;Z)I",
(void *)android_media_AudioEffect_native_setup}, (void *)android_media_AudioEffect_native_setup},
{"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize}, {"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize},
{"native_release", "()V", (void *)android_media_AudioEffect_native_release}, {"native_release", "()V", (void *)android_media_AudioEffect_native_release},