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

Commit 60a7931d authored by Android Build Prod User's avatar Android Build Prod User Committed by Android (Google) Code Review
Browse files

Merge changes from topic "fix-b-188932434-common-types-2"

* changes:
  Move common audio AIDL types to audio.media.audio.common
  MediaFormat: Add more audio MIME types
  Add android.media.audio.common.AidlConversion class
parents c4e6d930 1571010b
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -22635,16 +22635,32 @@ package android.media {
    field public static final String KEY_VIDEO_QP_P_MIN = "video-qp-p-min";
    field public static final String KEY_WIDTH = "width";
    field public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
    field public static final String MIMETYPE_AUDIO_AAC_ELD = "audio/mp4a.40.39";
    field public static final String MIMETYPE_AUDIO_AAC_HE_V1 = "audio/mp4a.40.05";
    field public static final String MIMETYPE_AUDIO_AAC_HE_V2 = "audio/mp4a.40.29";
    field public static final String MIMETYPE_AUDIO_AAC_LC = "audio/mp4a.40.02";
    field public static final String MIMETYPE_AUDIO_AAC_XHE = "audio/mp4a.40.42";
    field public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3";
    field public static final String MIMETYPE_AUDIO_AC4 = "audio/ac4";
    field public static final String MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
    field public static final String MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
    field public static final String MIMETYPE_AUDIO_DOLBY_MAT = "audio/vnd.dolby.mat";
    field public static final String MIMETYPE_AUDIO_DOLBY_TRUEHD = "audio/vnd.dolby.mlp";
    field public static final String MIMETYPE_AUDIO_DRA = "audio/vnd.dra";
    field public static final String MIMETYPE_AUDIO_DTS = "audio/vnd.dts";
    field public static final String MIMETYPE_AUDIO_DTS_HD = "audio/vnd.dts.hd";
    field public static final String MIMETYPE_AUDIO_DTS_UHD = "audio/vnd.dts.uhd";
    field public static final String MIMETYPE_AUDIO_EAC3 = "audio/eac3";
    field public static final String MIMETYPE_AUDIO_EAC3_JOC = "audio/eac3-joc";
    field public static final String MIMETYPE_AUDIO_FLAC = "audio/flac";
    field public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
    field public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
    field public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937";
    field public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
    field public static final String MIMETYPE_AUDIO_MPEGH_BL_L3 = "audio/mhm1.03";
    field public static final String MIMETYPE_AUDIO_MPEGH_BL_L4 = "audio/mhm1.04";
    field public static final String MIMETYPE_AUDIO_MPEGH_LC_L3 = "audio/mhm1.0d";
    field public static final String MIMETYPE_AUDIO_MPEGH_LC_L4 = "audio/mhm1.0e";
    field public static final String MIMETYPE_AUDIO_MPEGH_MHA1 = "audio/mha1";
    field public static final String MIMETYPE_AUDIO_MPEGH_MHM1 = "audio/mhm1";
    field public static final String MIMETYPE_AUDIO_MSGSM = "audio/gsm";
+9 −104
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.hardware.soundtrigger;

import android.annotation.Nullable;
import android.media.AudioFormat;
import android.media.audio.common.AidlConversion;
import android.media.audio.common.AudioConfig;
import android.media.soundtrigger.AudioCapabilities;
import android.media.soundtrigger.ConfidenceLevel;
@@ -197,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,
@@ -215,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,
@@ -224,107 +227,15 @@ class ConversionUtil {
                apiExtras);
    }

    public static AudioFormat aidl2apiAudioFormat(AudioConfig audioConfig) {
        AudioFormat.Builder apiBuilder = new AudioFormat.Builder();
        apiBuilder.setSampleRate(audioConfig.sampleRateHz);
        apiBuilder.setChannelMask(aidl2apiChannelInMask(audioConfig.channelMask));
        apiBuilder.setEncoding(aidl2apiEncoding(audioConfig.format));
        return apiBuilder.build();
    }

    // Same as above, but in case of a null input returns a non-null valid output.
    public static AudioFormat aidl2apiAudioFormatWithDefault(@Nullable AudioConfig audioConfig) {
    // In case of a null input returns a non-null valid output.
    public static AudioFormat aidl2apiAudioFormatWithDefault(
            @Nullable AudioConfig audioConfig, boolean isInput) {
        if (audioConfig != null) {
            return aidl2apiAudioFormat(audioConfig);
            return AidlConversion.aidl2api_AudioConfig_AudioFormat(audioConfig, isInput);
        }
        return new AudioFormat.Builder().build();
    }

    public static int aidl2apiEncoding(int aidlFormat) {
        switch (aidlFormat) {
            case android.media.audio.common.AudioFormat.PCM
                    | android.media.audio.common.AudioFormat.PCM_SUB_16_BIT:
                return AudioFormat.ENCODING_PCM_16BIT;

            case android.media.audio.common.AudioFormat.PCM
                    | android.media.audio.common.AudioFormat.PCM_SUB_8_BIT:
                return AudioFormat.ENCODING_PCM_8BIT;

            case android.media.audio.common.AudioFormat.PCM
                    | android.media.audio.common.AudioFormat.PCM_SUB_FLOAT:
            case android.media.audio.common.AudioFormat.PCM
                    | android.media.audio.common.AudioFormat.PCM_SUB_8_24_BIT:
            case android.media.audio.common.AudioFormat.PCM
                    | android.media.audio.common.AudioFormat.PCM_SUB_24_BIT_PACKED:
            case android.media.audio.common.AudioFormat.PCM
                    | android.media.audio.common.AudioFormat.PCM_SUB_32_BIT:
                return AudioFormat.ENCODING_PCM_FLOAT;

            case android.media.audio.common.AudioFormat.AC3:
                return AudioFormat.ENCODING_AC3;

            case android.media.audio.common.AudioFormat.E_AC3:
                return AudioFormat.ENCODING_E_AC3;

            case android.media.audio.common.AudioFormat.DTS:
                return AudioFormat.ENCODING_DTS;

            case android.media.audio.common.AudioFormat.DTS_HD:
                return AudioFormat.ENCODING_DTS_HD;

            case android.media.audio.common.AudioFormat.MP3:
                return AudioFormat.ENCODING_MP3;

            case android.media.audio.common.AudioFormat.AAC
                    | android.media.audio.common.AudioFormat.AAC_SUB_LC:
                return AudioFormat.ENCODING_AAC_LC;

            case android.media.audio.common.AudioFormat.AAC
                    | android.media.audio.common.AudioFormat.AAC_SUB_HE_V1:
                return AudioFormat.ENCODING_AAC_HE_V1;

            case android.media.audio.common.AudioFormat.AAC
                    | android.media.audio.common.AudioFormat.AAC_SUB_HE_V2:
                return AudioFormat.ENCODING_AAC_HE_V2;

            case android.media.audio.common.AudioFormat.IEC61937:
                return AudioFormat.ENCODING_IEC61937;

            case android.media.audio.common.AudioFormat.DOLBY_TRUEHD:
                return AudioFormat.ENCODING_DOLBY_TRUEHD;

            case android.media.audio.common.AudioFormat.AAC
                    | android.media.audio.common.AudioFormat.AAC_SUB_ELD:
                return AudioFormat.ENCODING_AAC_ELD;

            case android.media.audio.common.AudioFormat.AAC
                    | android.media.audio.common.AudioFormat.AAC_SUB_XHE:
                return AudioFormat.ENCODING_AAC_XHE;

            case android.media.audio.common.AudioFormat.AC4:
                return AudioFormat.ENCODING_AC4;

            case android.media.audio.common.AudioFormat.E_AC3
                    | android.media.audio.common.AudioFormat.E_AC3_SUB_JOC:
                return AudioFormat.ENCODING_E_AC3_JOC;

            case android.media.audio.common.AudioFormat.MAT:
            case android.media.audio.common.AudioFormat.MAT
                    | android.media.audio.common.AudioFormat.MAT_SUB_1_0:
            case android.media.audio.common.AudioFormat.MAT
                    | android.media.audio.common.AudioFormat.MAT_SUB_2_0:
            case android.media.audio.common.AudioFormat.MAT
                    | android.media.audio.common.AudioFormat.MAT_SUB_2_1:
                return AudioFormat.ENCODING_DOLBY_MAT;

            case android.media.audio.common.AudioFormat.DEFAULT:
                return AudioFormat.ENCODING_DEFAULT;

            default:
                return AudioFormat.ENCODING_INVALID;
        }
    }

    public static int api2aidlModelParameter(int apiParam) {
        switch (apiParam) {
            case ModelParams.THRESHOLD_FACTOR:
@@ -334,12 +245,6 @@ class ConversionUtil {
        }
    }

    public static int aidl2apiChannelInMask(int aidlMask) {
        // We're assuming AudioFormat.CHANNEL_IN_* constants are kept in sync with
        // android.media.audio.common.AudioChannelMask.
        return aidlMask;
    }

    public static SoundTrigger.ModelParamRange aidl2apiModelParameterRange(
            @Nullable ModelParameterRange aidlRange) {
        if (aidlRange == null) {
+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",
@@ -242,6 +243,7 @@ cc_library_shared {
            ],

            shared_libs: [
                "android.media.audio.common.types-V1-cpp",
                "audioclient-types-aidl-cpp",
                "audioflinger-aidl-cpp",
                "audiopolicy-types-aidl-cpp",
@@ -288,6 +290,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 {
@@ -1618,6 +1619,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));
}
Loading