AudioEffect: add contructor for device effect

Add a @SystemApi constructor to AudioEffect class
allowing to attach an audio effect to an input or output
device.

Bug: 136294538
Test: make
Change-Id: I0cb5cf5f38f95605a8605f3347aaa7e187db4e8a
Merged-In: I0cb5cf5f38f95605a8605f3347aaa7e187db4e8a
This commit is contained in:
Eric Laurent
2020-01-03 08:51:24 -08:00
parent 9f7e6eb601
commit a25bf98613
3 changed files with 66 additions and 7 deletions

View File

@@ -3819,6 +3819,14 @@ package android.media {
}
package android.media.audiofx {
public class AudioEffect {
ctor @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public AudioEffect(@NonNull java.util.UUID, @NonNull android.media.AudioDeviceAddress);
}
}
package android.media.audiopolicy {
public class AudioMix {

View File

@@ -16,11 +16,18 @@
package android.media.audiofx;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.AudioDeviceAddress;
import android.media.AudioDeviceInfo;
import android.media.AudioSystem;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -448,12 +455,46 @@ public class AudioEffect {
public AudioEffect(UUID type, UUID uuid, int priority, int audioSession)
throws IllegalArgumentException, UnsupportedOperationException,
RuntimeException {
this(type, uuid, priority, audioSession, null);
}
/**
* Constructs an AudioEffect attached to a particular audio device.
* The device does not have to be attached when the effect is created. The effect will only
* be applied when the device is actually selected for playback or capture.
* @param uuid unique identifier of a particular effect implementation.
* @param device the device the effect must be attached to.
*
* @throws java.lang.IllegalArgumentException
* @throws java.lang.UnsupportedOperationException
* @throws java.lang.RuntimeException
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
public AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAddress device) {
this(EFFECT_TYPE_NULL, Objects.requireNonNull(uuid), 0, -2, Objects.requireNonNull(device));
}
private AudioEffect(UUID type, UUID uuid, int priority,
int audioSession, @Nullable AudioDeviceAddress device)
throws IllegalArgumentException, UnsupportedOperationException,
RuntimeException {
int[] id = new int[1];
Descriptor[] desc = new Descriptor[1];
int deviceType = AudioSystem.DEVICE_NONE;
String deviceAddress = "";
if (device != null) {
deviceType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType());
deviceAddress = device.getAddress();
}
// native initialization
int initResult = native_setup(new WeakReference<AudioEffect>(this),
type.toString(), uuid.toString(), priority, audioSession, id,
desc, ActivityThread.currentOpPackageName());
type.toString(), uuid.toString(), priority, audioSession,
deviceType, deviceAddress,
id, desc, ActivityThread.currentOpPackageName());
if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
Log.e(TAG, "Error code " + initResult
+ " when initializing AudioEffect.");
@@ -1293,7 +1334,8 @@ public class AudioEffect {
private static native final void native_init();
private native final int native_setup(Object audioeffect_this, String type,
String uuid, int priority, int audioSession, int[] id, Object[] desc,
String uuid, int priority, int audioSession,
int deviceType, String deviceAddress, int[] id, Object[] desc,
String opPackageName);
private native final void native_finalize();

View File

@@ -268,8 +268,9 @@ android_media_AudioEffect_native_init(JNIEnv *env)
static jint
android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jstring type, jstring uuid, jint priority, jint sessionId, jintArray jId,
jobjectArray javadesc, jstring opPackageName)
jstring type, jstring uuid, jint priority, jint sessionId,
jint deviceType, jstring deviceAddress,
jintArray jId, jobjectArray javadesc, jstring opPackageName)
{
ALOGV("android_media_AudioEffect_native_setup");
AudioEffectJniStorage* lpJniStorage = NULL;
@@ -280,6 +281,7 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
const char *uuidStr = NULL;
effect_descriptor_t desc;
jobject jdesc;
AudioDeviceTypeAddr device;
ScopedUtfChars opPackageNameStr(env, opPackageName);
@@ -328,6 +330,12 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
goto setup_failure;
}
if (deviceType != AUDIO_DEVICE_NONE) {
device.mType = deviceType;
ScopedUtfChars address(env, deviceAddress);
device.mAddress = address.c_str();
}
// create the native AudioEffect object
lpAudioEffect = new AudioEffect(typeStr,
String16(opPackageNameStr.c_str()),
@@ -336,7 +344,8 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
effectCallback,
&lpJniStorage->mCallbackData,
(audio_session_t) sessionId,
AUDIO_IO_HANDLE_NONE);
AUDIO_IO_HANDLE_NONE,
device);
if (lpAudioEffect == 0) {
ALOGE("Error creating AudioEffect");
goto setup_failure;
@@ -757,7 +766,7 @@ android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz _
// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)android_media_AudioEffect_native_init},
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;II[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;)I",
(void *)android_media_AudioEffect_native_setup},
{"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize},
{"native_release", "()V", (void *)android_media_AudioEffect_native_release},