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

Commit 1571010b authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Move common audio AIDL types to audio.media.audio.common

The following types are being moved from 'android.media':
 - AudioChannelLayout
 - AudioFormatDescription
 - AudioFormatType
 - PcmType

AudioChannelLayout replaces legacy-based AudioChannelMask type.
AudioFormatDescription replaces legacy-based AudioFormat type.
Updated conversion functions.

Bug: 188932434
Test: atest AidlConversionUnitTests
Test: atest SoundHw2CompatTest
Test: atest SoundTriggerMiddlewareImplTest
Change-Id: Id002177f6b7f651389b59b0f476e6e2d28be4592
parent 7a4118bc
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -198,7 +198,8 @@ class ConversionUtil {
            int modelHandle, int captureSession, RecognitionEvent aidlEvent) {
        // The API recognition event doesn't allow for a null audio format, even though it doesn't
        // always make sense. We thus replace it with a default.
        AudioFormat audioFormat = aidl2apiAudioFormatWithDefault(aidlEvent.audioConfig);
        AudioFormat audioFormat = aidl2apiAudioFormatWithDefault(
                aidlEvent.audioConfig, true /*isInput*/);
        return new SoundTrigger.GenericRecognitionEvent(
                aidlEvent.status,
                modelHandle, aidlEvent.captureAvailable, captureSession,
@@ -216,7 +217,8 @@ class ConversionUtil {
        }
        // The API recognition event doesn't allow for a null audio format, even though it doesn't
        // always make sense. We thus replace it with a default.
        AudioFormat audioFormat = aidl2apiAudioFormatWithDefault(aidlEvent.common.audioConfig);
        AudioFormat audioFormat = aidl2apiAudioFormatWithDefault(
                aidlEvent.common.audioConfig, true /*isInput*/);
        return new SoundTrigger.KeyphraseRecognitionEvent(aidlEvent.common.status, modelHandle,
                aidlEvent.common.captureAvailable,
                captureSession, aidlEvent.common.captureDelayMs,
@@ -226,9 +228,10 @@ class ConversionUtil {
    }

    // In case of a null input returns a non-null valid output.
    public static AudioFormat aidl2apiAudioFormatWithDefault(@Nullable AudioConfig audioConfig) {
    public static AudioFormat aidl2apiAudioFormatWithDefault(
            @Nullable AudioConfig audioConfig, boolean isInput) {
        if (audioConfig != null) {
            return AidlConversion.aidl2api_AudioConfig_AudioFormat(audioConfig);
            return AidlConversion.aidl2api_AudioConfig_AudioFormat(audioConfig, isInput);
        }
        return new AudioFormat.Builder().build();
    }
+3 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ cc_library_shared {
                "android_util_CharsetUtils.cpp",
                "android_util_MemoryIntArray.cpp",
                "android_util_Process.cpp",
                "android_media_audio_common_AidlConversion.cpp",
                "android_media_AudioDeviceAttributes.cpp",
                "android_media_AudioEffectDescriptor.cpp",
                "android_media_AudioRecord.cpp",
@@ -241,6 +242,7 @@ cc_library_shared {
            ],

            shared_libs: [
                "android.media.audio.common.types-V1-cpp",
                "audioclient-types-aidl-cpp",
                "audioflinger-aidl-cpp",
                "av-types-aidl-cpp",
@@ -284,6 +286,7 @@ cc_library_shared {
                "libmediametrics",
                "libmeminfo",
                "libaudioclient",
                "libaudioclient_aidl_conversion",
                "libaudiofoundation",
                "libaudiopolicy",
                "libusbhost",
+2 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ extern int register_android_media_AudioVolumeGroups(JNIEnv *env);
extern int register_android_media_AudioVolumeGroupChangeHandler(JNIEnv *env);
extern int register_android_media_MicrophoneInfo(JNIEnv *env);
extern int register_android_media_ToneGenerator(JNIEnv *env);
extern int register_android_media_audio_common_AidlConversion(JNIEnv* env);
extern int register_android_media_midi(JNIEnv *env);

namespace android {
@@ -1616,6 +1617,7 @@ static const RegJNIRec gRegJNI[] = {
        REG_JNI(register_android_media_MicrophoneInfo),
        REG_JNI(register_android_media_RemoteDisplay),
        REG_JNI(register_android_media_ToneGenerator),
        REG_JNI(register_android_media_audio_common_AidlConversion),
        REG_JNI(register_android_media_midi),

        REG_JNI(register_android_opengl_classes),
+125 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "AidlConversion"

#include <android_os_Parcel.h>
#include <binder/Parcel.h>
#include <jni.h>
#include <log/log.h>
#include <media/AidlConversion.h>
#include <system/audio.h>

#include "core_jni_helpers.h"

namespace {

using namespace android;

#define PACKAGE "android/media/audio/common"
#define CLASSNAME PACKAGE "/AidlConversion"

template <typename AidlType, typename ConvFunc>
int aidl2legacy(JNIEnv* env, jobject clazz, jobject jParcel, const ConvFunc& conv,
                int fallbackValue) {
    if (Parcel* parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) {
        AidlType aidl{};
        if (status_t status = aidl.readFromParcel(parcel); status == OK) {
            auto legacy = conv(aidl);
            if (legacy.ok()) {
                return legacy.value();
            }
        } else {
            ALOGE("aidl2legacy: Failed to read from parcel: %d", status);
        }
    } else {
        ALOGE("aidl2legacy: Failed to retrieve the native parcel from Java parcel");
    }
    return fallbackValue;
}

template <typename LegacyType, typename ConvFunc>
jobject legacy2aidl(JNIEnv* env, jobject clazz, LegacyType legacy, const ConvFunc& conv) {
    auto aidl = conv(legacy);
    if (!aidl.ok()) {
        return 0;
    }
    if (jobject jParcel = createJavaParcelObject(env); jParcel != 0) {
        if (Parcel* parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) {
            if (status_t status = aidl.value().writeToParcel(parcel); status == OK) {
                parcel->setDataPosition(0);
                return jParcel;
            }
        } else {
            ALOGE("legacy2aidl: Failed to retrieve the native parcel from Java parcel");
        }
        env->DeleteLocalRef(jParcel);
    } else {
        ALOGE("legacy2aidl: Failed to create Java parcel");
    }
    return 0;
}

int aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t(JNIEnv* env, jobject clazz,
                                                               jobject jParcel, jboolean isInput) {
    return aidl2legacy<media::audio::common::AudioChannelLayout>(
            env, clazz, jParcel,
            [isInput](const media::audio::common::AudioChannelLayout& l) {
                return aidl2legacy_AudioChannelLayout_audio_channel_mask_t(l, isInput);
            },
            AUDIO_CHANNEL_INVALID);
}

jobject legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel(
        JNIEnv* env, jobject clazz, int /*audio_channel_mask_t*/ legacy, jboolean isInput) {
    return legacy2aidl<audio_channel_mask_t>(
            env, clazz, static_cast<audio_channel_mask_t>(legacy),
            [isInput](audio_channel_mask_t m) {
                return legacy2aidl_audio_channel_mask_t_AudioChannelLayout(m, isInput);
            });
}

int aidl2legacy_AudioFormatDescription_Parcel_audio_format_t(JNIEnv* env, jobject clazz,
                                                             jobject jParcel) {
    return aidl2legacy<
            media::audio::common::
                    AudioFormatDescription>(env, clazz, jParcel,
                                            aidl2legacy_AudioFormatDescription_audio_format_t,
                                            AUDIO_FORMAT_INVALID);
}

jobject legacy2aidl_audio_format_t_AudioFormatDescription_Parcel(JNIEnv* env, jobject clazz,
                                                                 int /*audio_format_t*/ legacy) {
    return legacy2aidl<audio_format_t>(env, clazz, static_cast<audio_format_t>(legacy),
                                       legacy2aidl_audio_format_t_AudioFormatDescription);
}

const JNINativeMethod gMethods[] = {
        {"aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t", "(Landroid/os/Parcel;Z)I",
         reinterpret_cast<void*>(aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t)},
        {"legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel", "(IZ)Landroid/os/Parcel;",
         reinterpret_cast<void*>(legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel)},
        {"aidl2legacy_AudioFormatDescription_Parcel_audio_format_t", "(Landroid/os/Parcel;)I",
         reinterpret_cast<void*>(aidl2legacy_AudioFormatDescription_Parcel_audio_format_t)},
        {"legacy2aidl_audio_format_t_AudioFormatDescription_Parcel", "(I)Landroid/os/Parcel;",
         reinterpret_cast<void*>(legacy2aidl_audio_format_t_AudioFormatDescription_Parcel)},
};

} // namespace

int register_android_media_audio_common_AidlConversion(JNIEnv* env) {
    return RegisterMethodsOrDie(env, CLASSNAME, gMethods, NELEM(gMethods));
}
+18 −5
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ aidl_interface {
        "aidl/android/media/soundtrigger_middleware/SoundTriggerModuleDescriptor.aidl",
    ],
    imports: [
        "android.media.audio.common.types",
        "android.media.soundtrigger.types",
        "media_permission-aidl",
    ],
@@ -45,20 +46,29 @@ aidl_interface {
    vendor_available: true,
    host_supported: true,
    double_loadable: true,
    flags: ["-Werror", "-Weverything", ],
    flags: [
        "-Werror",
        "-Weverything",
    ],
    local_include_dir: "aidl",
    srcs: [
        "aidl/android/media/audio/common/AudioChannelMask.aidl",
        "aidl/android/media/audio/common/AudioChannelLayout.aidl",
        "aidl/android/media/audio/common/AudioConfig.aidl",
        "aidl/android/media/audio/common/AudioFormat.aidl",
        "aidl/android/media/audio/common/AudioFormatDescription.aidl",
        "aidl/android/media/audio/common/AudioFormatType.aidl",
        "aidl/android/media/audio/common/AudioOffloadInfo.aidl",
        "aidl/android/media/audio/common/AudioStreamType.aidl",
        "aidl/android/media/audio/common/AudioUsage.aidl",
        "aidl/android/media/audio/common/PcmType.aidl",
    ],
    stability: "vintf",
    backend: {
        cpp: {
            enabled: true,
            min_sdk_version: "29",
            apex_available: [
                "//apex_available:platform",
                "com.android.media",
            ],
        },
        java: {
            sdk_version: "module_current",
@@ -74,7 +84,10 @@ aidl_interface {
aidl_interface {
    name: "android.media.soundtrigger.types",
    vendor_available: true,
    flags: ["-Werror", "-Weverything", ],
    flags: [
        "-Werror",
        "-Weverything",
    ],
    local_include_dir: "aidl",
    srcs: [
        "aidl/android/media/soundtrigger/AudioCapabilities.aidl",
Loading