Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62812aa8 authored by Hayden Gomes's avatar Hayden Gomes
Browse files

Add API for setting supported system usages

By default, a device won't support any system usages until
AudioManager#setSupportedSystemUsages is called

System Usages will be checked when requesting/abandoning audio focus,
and when tracking players.

Bug: 141006627
Test: called setSupportedSystemUsages and verified both dumpsys included
expected values

Change-Id: I65ebb8f9b03dfd759b7142609871589ed7342f67
parent fe2c8775
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4124,6 +4124,7 @@ package android.media {
    method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
    method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAddress getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
    method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
    method public boolean isAudioServerRunning();
    method public boolean isHdmiSystemAudioSupported();
@@ -4136,6 +4137,7 @@ package android.media {
    method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAddress);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
+8 −12
Original line number Diff line number Diff line
@@ -48,9 +48,7 @@ static struct {
    jfieldID    mFormattedTags; // AudioAttributes.mFormattedTags
} gAudioAttributesFields;

static struct {
    jmethodID isSystemUsage;
} gAudioAttributesClassMethods;
static struct { jmethodID isSystemUsage; } gAudioAttributesClassMethods;

static jclass gAudioAttributesBuilderClass;
static jmethodID gAudioAttributesBuilderCstor;
@@ -120,11 +118,9 @@ static jint nativeAudioAttributesToJavaAudioAttributes(
                                                      attributes.usage);
    if (isSystemUsage) {
        env->CallObjectMethod(jAttributeBuilder.get(),
                                  gAudioAttributesBuilderMethods.setSystemUsage,
                                  attributes.usage);
                              gAudioAttributesBuilderMethods.setSystemUsage, attributes.usage);
    } else {
        env->CallObjectMethod(jAttributeBuilder.get(),
                              gAudioAttributesBuilderMethods.setUsage,
        env->CallObjectMethod(jAttributeBuilder.get(), gAudioAttributesBuilderMethods.setUsage,
                              attributes.usage);
    }
    env->CallObjectMethod(jAttributeBuilder.get(),
@@ -183,8 +179,8 @@ int register_android_media_AudioAttributes(JNIEnv *env)
{
    jclass audioAttributesClass = FindClassOrDie(env, kClassPathName);
    gAudioAttributesClass = MakeGlobalRefOrDie(env, audioAttributesClass);
    gAudioAttributesClassMethods.isSystemUsage = GetStaticMethodIDOrDie(env, gAudioAttributesClass,
        "isSystemUsage", "(I)Z");
    gAudioAttributesClassMethods.isSystemUsage =
            GetStaticMethodIDOrDie(env, gAudioAttributesClass, "isSystemUsage", "(I)Z");

    gAudioAttributesFields.mUsage = GetFieldIDOrDie(env, audioAttributesClass, "mUsage", "I");
    gAudioAttributesFields.mSource = GetFieldIDOrDie(env, audioAttributesClass, "mSource", "I");
@@ -204,8 +200,8 @@ int register_android_media_AudioAttributes(JNIEnv *env)
    gAudioAttributesBuilderMethods.setUsage = GetMethodIDOrDie(
                env, audioAttributesBuilderClass, "setUsage",
                "(I)Landroid/media/AudioAttributes$Builder;");
    gAudioAttributesBuilderMethods.setSystemUsage = GetMethodIDOrDie(
                    env, audioAttributesBuilderClass, "setSystemUsage",
    gAudioAttributesBuilderMethods.setSystemUsage =
            GetMethodIDOrDie(env, audioAttributesBuilderClass, "setSystemUsage",
                             "(I)Landroid/media/AudioAttributes$Builder;");
    gAudioAttributesBuilderMethods.setInternalCapturePreset = GetMethodIDOrDie(
                env, audioAttributesBuilderClass, "setInternalCapturePreset",
+26 −0
Original line number Diff line number Diff line
@@ -2239,6 +2239,31 @@ android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
    return AudioSystem::isHapticPlaybackSupported();
}

static jint android_media_AudioSystem_setSupportedSystemUsages(JNIEnv *env, jobject thiz,
                                                               jintArray systemUsages) {
    std::vector<audio_usage_t> nativeSystemUsagesVector;

    if (systemUsages == nullptr) {
        return (jint) AUDIO_JAVA_BAD_VALUE;
    }

    int *nativeSystemUsages = nullptr;
    nativeSystemUsages = env->GetIntArrayElements(systemUsages, 0);

    if (nativeSystemUsages != nullptr) {
        jsize len = env->GetArrayLength(systemUsages);
        for (size_t i = 0; i < len; i++) {
            audio_usage_t nativeAudioUsage =
                    static_cast<audio_usage_t>(nativeSystemUsages[i]);
            nativeSystemUsagesVector.push_back(nativeAudioUsage);
        }
        env->ReleaseIntArrayElements(systemUsages, nativeSystemUsages, 0);
    }

    status_t status = AudioSystem::setSupportedSystemUsages(nativeSystemUsagesVector);
    return (jint)nativeToJavaStatus(status);
}

static jint
android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) {
    return AudioSystem::setAllowedCapturePolicy(uid, flags);
@@ -2430,6 +2455,7 @@ static const JNINativeMethod gMethods[] = {
    {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
    {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
                    (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
    {"setSupportedSystemUsages", "([I)I", (void *)android_media_AudioSystem_setSupportedSystemUsages},
    {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
    {"setRttEnabled",       "(Z)I",     (void *)android_media_AudioSystem_setRttEnabled},
    {"setAudioHalPids",  "([I)I", (void *)android_media_AudioSystem_setAudioHalPids},
+1 −1
Original line number Diff line number Diff line
@@ -735,7 +735,7 @@ public final class AudioAttributes implements Parcelable {
        }

        /**
         * Sets the attribute describing what is the intended use of the the audio signal,
         * Sets the attribute describing what is the intended use of the audio signal,
         * such as alarm or ringtone.
         * @param usage one of {@link AttributeSdkUsage#USAGE_UNKNOWN},
         *     {@link AttributeSdkUsage#USAGE_MEDIA},
+34 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes.AttributeSystemUsage;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener;
import android.media.audiopolicy.AudioProductStrategy;
@@ -1267,6 +1268,39 @@ public class AudioManager {
        }
    }

    /**
     * Set the system usages to be supported on this device.
     * @param systemUsages array of system usages to support {@link AttributeSystemUsage}
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
        Objects.requireNonNull(systemUsages, "systemUsages must not be null");
        final IAudioService service = getService();
        try {
            service.setSupportedSystemUsages(systemUsages);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Get the system usages supported on this device.
     * @return array of supported system usages {@link AttributeSystemUsage}
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
        final IAudioService service = getService();
        try {
            return service.getSupportedSystemUsages();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Solo or unsolo a particular stream.
     * <p>
Loading