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

Commit 4385272c authored by Oscar Azucena's avatar Oscar Azucena Committed by Android (Google) Code Review
Browse files

Merge changes from topic "mz_step_4" into main

* changes:
  Add audio permission check to audio product strategies
  audio: multizones readiness: add zone ID to strategy
parents fedc5eab c8985eb7
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -7659,7 +7659,7 @@ package android.media {
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getActiveAssistantServicesUids();
    method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getAssistantServicesUids();
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
    method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioRecord getCallDownlinkExtractionAudioRecord(@NonNull android.media.AudioFormat);
    method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioTrack getCallUplinkInjectionAudioTrack(@NonNull android.media.AudioFormat);
@@ -7678,6 +7678,7 @@ package android.media {
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public int getStreamTypeAlias(int);
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes, int);
    method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupMaxVolumeIndex(int);
    method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupMinVolumeIndex(int);
    method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupVolumeIndex(int);
@@ -8205,14 +8206,22 @@ package android.media.audiopolicy {
  }
  public final class AudioProductStrategy implements android.os.Parcelable {
    method @NonNull public static android.media.audiopolicy.AudioProductStrategy createInvalidAudioProductStrategy(int);
    method public int describeContents();
    method @NonNull public android.media.AudioAttributes getAudioAttributes();
    method public int getId();
    method @NonNull public String getName();
    method public boolean supportsAudioAttributes(@NonNull android.media.AudioAttributes);
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public static android.media.audiopolicy.AudioProductStrategy createInvalidAudioProductStrategy(int);
    method public int describeContents();
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public android.media.AudioAttributes getAudioAttributes();
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public static android.media.audiopolicy.AudioProductStrategy getAudioProductStrategyForAudioAttributes(@NonNull android.media.AudioAttributes, int, boolean);
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getId();
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public String getName();
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public static int getVolumeGroupIdForAudioAttributes(@NonNull android.media.AudioAttributes, int, boolean);
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getVolumeGroupIdForAudioAttributes(@NonNull android.media.AudioAttributes, int);
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getZoneId();
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public static int getZoneIdForAudioVolumeGroupId(int);
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean supportsAudioAttributes(@NonNull android.media.AudioAttributes);
    method @FlaggedApi("android.media.audiopolicy.multi_zone_audio") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean supportsAudioAttributes(@NonNull android.media.AudioAttributes, int);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategy> CREATOR;
    field @FlaggedApi("android.media.audiopolicy.multi_zone_audio") public static final int DEFAULT_ZONE_ID = 0; // 0x0
    field @FlaggedApi("android.media.audiopolicy.multi_zone_audio") public static final int INVALID_ZONE_ID = -1; // 0xffffffff
  }
  public final class AudioVolumeGroup implements android.os.Parcelable {
+37 −16
Original line number Diff line number Diff line
@@ -104,37 +104,43 @@ static jint nativeAudioAttributesFromJavaAudioAttributes(
    return (jint)AUDIO_JAVA_SUCCESS;
}

static jint nativeAudioAttributesToJavaAudioAttributes(
        JNIEnv* env, jobject *jAudioAttributes, const audio_attributes_t &attributes)
static jint nativeAudioAttributesToJavaAudioAttributesBuilder(
        JNIEnv* env, jobject jAudioAttributesBuilder, const audio_attributes_t &attributes)
{
    ScopedLocalRef<jobject> jAttributeBuilder(env, env->NewObject(gAudioAttributesBuilderClass,
                                                                  gAudioAttributesBuilderCstor));
    if (jAttributeBuilder.get() == nullptr) {
        return (jint)AUDIO_JAVA_ERROR;
    }

    const bool isSystemUsage = env->CallStaticBooleanMethod(gAudioAttributesClass,
                                                      gAudioAttributesClassMethods.isSystemUsage,
                                                      attributes.usage);
        gAudioAttributesClassMethods.isSystemUsage, attributes.usage);
    if (isSystemUsage) {
        env->CallObjectMethod(jAttributeBuilder.get(),
        env->CallObjectMethod(jAudioAttributesBuilder,
                              gAudioAttributesBuilderMethods.setSystemUsage, attributes.usage);
    } else {
        env->CallObjectMethod(jAttributeBuilder.get(), gAudioAttributesBuilderMethods.setUsage,
        env->CallObjectMethod(jAudioAttributesBuilder, gAudioAttributesBuilderMethods.setUsage,
                              attributes.usage);
    }
    env->CallObjectMethod(jAttributeBuilder.get(),
    env->CallObjectMethod(jAudioAttributesBuilder,
                          gAudioAttributesBuilderMethods.setInternalCapturePreset,
                          attributes.source);
    env->CallObjectMethod(jAttributeBuilder.get(),
    env->CallObjectMethod(jAudioAttributesBuilder,
                          gAudioAttributesBuilderMethods.setInternalContentType,
                          attributes.content_type);
    env->CallObjectMethod(jAttributeBuilder.get(),
    env->CallObjectMethod(jAudioAttributesBuilder,
                          gAudioAttributesBuilderMethods.replaceFlags,
                          attributes.flags);
    env->CallObjectMethod(jAttributeBuilder.get(),
    env->CallObjectMethod(jAudioAttributesBuilder,
                          gAudioAttributesBuilderMethods.addTag,
                          env->NewStringUTF(attributes.tags));
    return (jint)AUDIO_JAVA_SUCCESS;
}

static jint nativeAudioAttributesToJavaAudioAttributes(
        JNIEnv* env, jobject *jAudioAttributes, const audio_attributes_t &attributes)
{
    ScopedLocalRef<jobject> jAttributeBuilder(env, env->NewObject(gAudioAttributesBuilderClass,
                                                                  gAudioAttributesBuilderCstor));
    if (jAttributeBuilder.get() == nullptr) {
        return (jint)AUDIO_JAVA_ERROR;
    }

    nativeAudioAttributesToJavaAudioAttributesBuilder(env, jAttributeBuilder.get(), attributes);

    *jAudioAttributes = env->CallObjectMethod(jAttributeBuilder.get(),
                                              gAudioAttributesBuilderMethods.build);
@@ -161,6 +167,13 @@ jint JNIAudioAttributeHelper::nativeToJava(
    return nativeAudioAttributesToJavaAudioAttributes(env, jAudioAttributes, attributes);
}


jint JNIAudioAttributeHelper::nativeToJavaBuilder(
        JNIEnv* env, jobject jAttributesBuilder, const audio_attributes_t &attributes)
{
    return nativeAudioAttributesToJavaAudioAttributesBuilder(env, jAttributesBuilder, attributes);
}

jint JNIAudioAttributeHelper::getJavaArray(
        JNIEnv* env, jobjectArray *jAudioAttributeArray, jint numAudioAttributes)
{
@@ -168,6 +181,14 @@ jint JNIAudioAttributeHelper::getJavaArray(
    return *jAudioAttributeArray == NULL? (jint)AUDIO_JAVA_ERROR : (jint)AUDIO_JAVA_SUCCESS;
}

bool JNIAudioAttributeHelper::isInstanceOfAudioAttributes(JNIEnv *env, jobject object) {
    return env->IsInstanceOf(object, gAudioAttributesClass);
}

bool JNIAudioAttributeHelper::isInstanceOfAudioAttributesBuilder(JNIEnv *env, jobject object) {
    return env->IsInstanceOf(object, gAudioAttributesBuilderClass);
}

/*
 * JNI registration.
 */
+14 −0
Original line number Diff line number Diff line
@@ -60,6 +60,16 @@ public:
    static jint nativeToJava(
            JNIEnv* env, jobject *jAudioAttributes, const audio_attributes_t &attributes);

    /**
     * @brief nativeToJava AudioAttributes.Builder Java object from a native AudioAttributes.
     * @param env
     * @param jAttributesBuilder JAVA AudioAttribute.Builder object
     * @param attributes native AudioAttribute
     * @return AUDIO_JAVA_SUCCESS on success, error code otherwise
     */
    static jint nativeToJavaBuilder(
            JNIEnv* env, jobject jAttributesBuilder, const audio_attributes_t &attributes);

    /**
     * @brief getJavaArray: creates an array of JAVA AudioAttributes objects
     * @param env
@@ -69,6 +79,10 @@ public:
     */
    static jint getJavaArray(
            JNIEnv* env, jobjectArray *jAudioAttributeArray, jint numAudioAttributes);

    static bool isInstanceOfAudioAttributes(JNIEnv *env, jobject object);

    static bool isInstanceOfAudioAttributesBuilder(JNIEnv *env, jobject object);
};

}; // namespace android
+80 −2
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ static jmethodID gAudioProductStrategyCstor;
static struct {
    jfieldID    mAudioAttributesGroups;
    jfieldID    mName;
    jfieldID    mZoneId;
    jfieldID    mId;
} gAudioProductStrategyFields;

@@ -79,11 +80,13 @@ static jint convertAudioProductStrategiesFromNative(
    jobject jAudioAttribute = NULL;
    jstring jName = NULL;
    jint jStrategyId = NULL;
    jint jZoneId = NULL;
    jint numAttributesGroups;
    size_t indexGroup = 0;

    jName = env->NewStringUTF(strategy.getName().c_str());
    jStrategyId = static_cast<jint>(strategy.getId());
    jZoneId = static_cast<jint>(strategy.getZoneId());

    // Audio Attributes Group array
    int attrGroupIndex = 0;
@@ -150,7 +153,7 @@ static jint convertAudioProductStrategiesFromNative(
    }
    *jAudioStrategy = env->NewObject(gAudioProductStrategyClass, gAudioProductStrategyCstor,
                                     jName,
                                     jStrategyId,
                                     jStrategyId, jZoneId,
                                     jAudioAttributesGroups);
exit:
    if (jAudioAttributes != NULL) {
@@ -169,6 +172,74 @@ exit:
    return jStatus;
}

static jint android_media_AudioSystem_getAudioAttributesForLegacyStream(JNIEnv *env, jobject clazz,
                                                                       jint jStreamType,
                                                                       jobject jAttributesBuilder) {
    if (env == NULL) {
        return AUDIO_JAVA_DEAD_OBJECT;
    }

    if (jAttributesBuilder == NULL) {
        ALOGE("%s: NULL AudioAttributes.Builder", __func__);
        return (jint)AUDIO_JAVA_BAD_VALUE;
    }

    if (!JNIAudioAttributeHelper::isInstanceOfAudioAttributesBuilder(env, jAttributesBuilder)) {
        ALOGE("%s: not an AudioAttributes", __func__);
        return (jint)AUDIO_JAVA_BAD_VALUE;
    }

    audio_attributes_t attributes;
    status_t status = AudioSystem::getAttributesForStreamType((audio_stream_type_t)jStreamType,
                                                          attributes);

    if (status != NO_ERROR) {
        ALOGE("%s: error getting audio attributes for stream %d", __func__, jStreamType);
        return nativeToJavaStatus(status);
    }

    status = JNIAudioAttributeHelper::nativeToJavaBuilder(env, jAttributesBuilder, attributes);

    if (status != NO_ERROR) {
        ALOGE("getAudioAttributesForLegacyStream error %d", status);
        return nativeToJavaStatus(status);
    }

    return AUDIO_JAVA_SUCCESS;
}

static jint android_media_AudioSystem_getLegacyStreamForAudioAttributes(JNIEnv *env, jobject clazz,
                                                                       jobject jattributes) {
    if (env == NULL) {
        return (jint)AUDIO_STREAM_DEFAULT;
    }

    if (jattributes == NULL) {
        ALOGE("%s: NULL AudioAttributes", __func__);
        return (jint)AUDIO_STREAM_DEFAULT;
    }

    if (!JNIAudioAttributeHelper::isInstanceOfAudioAttributes(env, jattributes)) {
        ALOGE("%s not an AudioAttributes", __func__ );
        return (jint)AUDIO_STREAM_DEFAULT;
    }

    audio_attributes_t attributes;
    int status = JNIAudioAttributeHelper::nativeFromJava(env, jattributes, &attributes);

    if (status != NO_ERROR) {
        ALOGE("%s error %d", __func__,  status);
        return (jint)AUDIO_STREAM_DEFAULT;;
    }
    audio_stream_type_t type;
    status = AudioSystem::getStreamTypeForAttributes(attributes, type);
    if (status != NO_ERROR) {
        ALOGE("%s error %d", __func__, status);
        return (jint)AUDIO_STREAM_DEFAULT;;
    }
    return (jint)type;
}

static jint
android_media_AudioSystem_listAudioProductStrategies(JNIEnv *env, jobject clazz,
                                                     jobject jStrategies)
@@ -215,6 +286,10 @@ exit:
static const JNINativeMethod gMethods[] = {
    {"native_list_audio_product_strategies", "(Ljava/util/ArrayList;)I",
                        (void *)android_media_AudioSystem_listAudioProductStrategies},
    {"native_get_audio_attributes_for_legacy_stream", "(ILandroid/media/AudioAttributes$Builder;)I",
     (void *)android_media_AudioSystem_getAudioAttributesForLegacyStream},
    {"native_get_legacy_stream_for_audio_attributes", "(Landroid/media/AudioAttributes;)I",
     (void *)android_media_AudioSystem_getLegacyStreamForAudioAttributes},
};

int register_android_media_AudioProductStrategies(JNIEnv *env)
@@ -229,7 +304,8 @@ int register_android_media_AudioProductStrategies(JNIEnv *env)
    gAudioProductStrategyClass = MakeGlobalRefOrDie(env, audioProductStrategyClass);
    gAudioProductStrategyCstor = GetMethodIDOrDie(
                env, audioProductStrategyClass, "<init>",
                "(Ljava/lang/String;I[Landroid/media/audiopolicy/AudioProductStrategy$AudioAttributesGroup;)V");
                "(Ljava/lang/String;"
                "II[Landroid/media/audiopolicy/AudioProductStrategy$AudioAttributesGroup;)V");
    gAudioProductStrategyFields.mAudioAttributesGroups = GetFieldIDOrDie(
                env, audioProductStrategyClass, "mAudioAttributesGroups",
                "[Landroid/media/audiopolicy/AudioProductStrategy$AudioAttributesGroup;");
@@ -237,6 +313,8 @@ int register_android_media_AudioProductStrategies(JNIEnv *env)
                env, audioProductStrategyClass, "mName", "Ljava/lang/String;");
    gAudioProductStrategyFields.mId = GetFieldIDOrDie(
                env, audioProductStrategyClass, "mId", "I");
    gAudioProductStrategyFields.mZoneId = GetFieldIDOrDie(
                env, audioProductStrategyClass, "mZoneId", "I");

    jclass audioAttributesGroupClass = FindClassOrDie(env, kAudioAttributesGroupsClassPathName);
    gAudioAttributesGroupClass = MakeGlobalRefOrDie(env, audioAttributesGroupClass);
+14 −0
Original line number Diff line number Diff line
@@ -896,6 +896,18 @@ static jint android_media_AudioSystem_setMaxVolumeIndexForGroup(JNIEnv *env, job
            AudioSystem::setMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index));
}

static jint android_media_AudioSystem_getVolumeGroupIdForStreamType(JNIEnv *env, jobject thiz,
                                                                jint stream) {
    int group;
    status_t status = AudioSystem::getVolumeGroupIdForStreamType(
            static_cast<audio_stream_type_t>(stream), group);
    if (status != NO_ERROR) {
        ALOGE("%s AudioSystem::getVolumeGroupIdForStreamType error %d", __func__, status);
        group = -1;
    }
    return group;
}

static jint
android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
{
@@ -3566,6 +3578,8 @@ static const JNINativeMethod gMethods[] = {
                               android_media_AudioSystem_getMaxVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("setMaxVolumeIndexForGroup", "(II)I",
                               android_media_AudioSystem_setMaxVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("getVolumeGroupIdForStreamType", "(I)I",
                               android_media_AudioSystem_getVolumeGroupIdForStreamType),
        MAKE_AUDIO_SYSTEM_METHOD(setMasterVolume),
        MAKE_AUDIO_SYSTEM_METHOD(getMasterVolume),
        MAKE_AUDIO_SYSTEM_METHOD(setMasterMute),
Loading