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

Commit 88375244 authored by Jiabin Huang's avatar Jiabin Huang Committed by Automerger Merge Worker
Browse files

Merge "Add short audio descriptor and encapsulation type in AudioProfile."...

Merge "Add short audio descriptor and encapsulation type in AudioProfile." into sc-dev am: ae6711b2

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13784568

Change-Id: I4859329c63608a6679727d9111e2212d5154eca6
parents 8b4cc363 ae6711b2
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -20147,6 +20147,14 @@ package android.media {
    method public android.media.AudioAttributes.Builder setUsage(int);
  }
  public class AudioDescriptor {
    method @NonNull public byte[] getDescriptor();
    method public int getEncapsulationType();
    method public int getStandard();
    field public static final int STANDARD_EDID = 1; // 0x1
    field public static final int STANDARD_NONE = 0; // 0x0
  }
  public abstract class AudioDeviceCallback {
    ctor public AudioDeviceCallback();
    method public void onAudioDevicesAdded(android.media.AudioDeviceInfo[]);
@@ -20155,6 +20163,7 @@ package android.media {
  public final class AudioDeviceInfo {
    method @NonNull public String getAddress();
    method @NonNull public java.util.List<android.media.AudioDescriptor> getAudioDescriptors();
    method @NonNull public java.util.List<android.media.AudioProfile> getAudioProfiles();
    method @NonNull public int[] getChannelCounts();
    method @NonNull public int[] getChannelIndexMasks();
@@ -20617,8 +20626,11 @@ package android.media {
  public class AudioProfile {
    method @NonNull public int[] getChannelIndexMasks();
    method @NonNull public int[] getChannelMasks();
    method public int getEncapsulationType();
    method public int getFormat();
    method @NonNull public int[] getSampleRates();
    field public static final int AUDIO_ENCAPSULATION_TYPE_IEC61937 = 1; // 0x1
    field public static final int AUDIO_ENCAPSULATION_TYPE_NONE = 0; // 0x0
  }
  public class AudioRecord implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
+46 −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.
 */

#ifndef ANDROID_MEDIA_EXTRAAUDIODESCRIPTOR_H
#define ANDROID_MEDIA_EXTRAAUDIODESCRIPTOR_H

#include <system/audio.h>
#include <utils/Errors.h>

namespace android {

// keep these values in sync with ExtraAudioDescriptor.java
#define STANDARD_NONE 0
#define STANDARD_EDID 1

static inline status_t audioStandardFromNative(audio_standard_t nStandard, int* standard) {
    status_t result = NO_ERROR;
    switch (nStandard) {
        case AUDIO_STANDARD_NONE:
            *standard = STANDARD_NONE;
            break;
        case AUDIO_STANDARD_EDID:
            *standard = STANDARD_EDID;
            break;
        default:
            result = BAD_VALUE;
    }
    return result;
}

} // namespace android

#endif // ANDROID_MEDIA_EXTRAAUDIODESCRIPTOR_H
 No newline at end of file
+47 −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.
 */

#ifndef ANDROID_MEDIA_AUDIOPROFILE_H
#define ANDROID_MEDIA_AUDIOPROFILE_H

#include <system/audio.h>
#include <utils/Errors.h>

namespace android {

// keep these values in sync with AudioProfile.java
#define ENCAPSULATION_TYPE_NONE 0
#define ENCAPSULATION_TYPE_IEC61937 1

static inline status_t audioEncapsulationTypeFromNative(
        audio_encapsulation_type_t nEncapsulationType, int* encapsulationType) {
    status_t result = NO_ERROR;
    switch (nEncapsulationType) {
        case AUDIO_ENCAPSULATION_TYPE_NONE:
            *encapsulationType = ENCAPSULATION_TYPE_NONE;
            break;
        case AUDIO_ENCAPSULATION_TYPE_IEC61937:
            *encapsulationType = ENCAPSULATION_TYPE_IEC61937;
            break;
        default:
            result = BAD_VALUE;
    }
    return result;
}

} // namespace android

#endif // ANDROID_MEDIA_AUDIOPROFILE_H
 No newline at end of file
+62 −4
Original line number Diff line number Diff line
@@ -34,10 +34,12 @@
#include <system/audio.h>
#include <system/audio_policy.h>
#include "android_media_AudioAttributes.h"
#include "android_media_AudioDescriptor.h"
#include "android_media_AudioDeviceAttributes.h"
#include "android_media_AudioEffectDescriptor.h"
#include "android_media_AudioErrors.h"
#include "android_media_AudioFormat.h"
#include "android_media_AudioProfile.h"
#include "android_media_MicrophoneInfo.h"

// ----------------------------------------------------------------------------
@@ -176,6 +178,9 @@ static struct {

static struct { jmethodID add; } gListMethods;

static jclass gAudioDescriptorClass;
static jmethodID gAudiODescriptorCstor;

//
// JNI Initialization for OpenSLES routing
//
@@ -1217,6 +1222,7 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
    jobject jAudioPortConfig = NULL;
    jstring jDeviceName = NULL;
    jobject jAudioProfiles = NULL;
    jobject jAudioDescriptors = nullptr;
    bool useInMask;

    ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
@@ -1293,13 +1299,21 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
            }
        }

        int encapsulationType;
        if (audioEncapsulationTypeFromNative(nAudioPort->audio_profiles[i].encapsulation_type,
                                             &encapsulationType) != NO_ERROR) {
            ALOGW("Unknown encapsualtion type for JAVA API: %u",
                  nAudioPort->audio_profiles[i].encapsulation_type);
            continue;
        }

        ScopedLocalRef<jobject>
                jAudioProfile(env,
                              env->NewObject(gAudioProfileClass, gAudioProfileCstor,
                                             audioFormatFromNative(
                                                     nAudioPort->audio_profiles[i].format),
                                             jSamplingRates.get(), jChannelMasks.get(),
                                             jChannelIndexMasks.get()));
                                             jChannelIndexMasks.get(), encapsulationType));
        if (jAudioProfile == nullptr) {
            jStatus = (jint)AUDIO_JAVA_ERROR;
            goto exit;
@@ -1307,6 +1321,42 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
        env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add, jAudioProfile.get());
    }

    jAudioDescriptors = env->NewObject(gArrayListClass, gArrayListMethods.cstor);
    if (jAudioDescriptors == nullptr) {
        jStatus = (jint)AUDIO_JAVA_ERROR;
        goto exit;
    }
    for (size_t i = 0; i < nAudioPort->num_extra_audio_descriptors; ++i) {
        const auto &extraAudioDescriptor = nAudioPort->extra_audio_descriptors[i];
        ScopedLocalRef<jobject> jAudioDescriptor(env);
        if (extraAudioDescriptor.descriptor_length == 0) {
            continue;
        }
        int standard;
        if (audioStandardFromNative(extraAudioDescriptor.standard, &standard) != NO_ERROR) {
            ALOGW("Unknown standard for JAVA API: %u", extraAudioDescriptor.standard);
            continue;
        }
        int encapsulationType;
        if (audioEncapsulationTypeFromNative(extraAudioDescriptor.encapsulation_type,
                                             &encapsulationType) != NO_ERROR) {
            ALOGW("Unknown encapsualtion type for JAVA API: %u",
                  extraAudioDescriptor.encapsulation_type);
            continue;
        }
        ScopedLocalRef<jbyteArray> jDescriptor(env,
                                               env->NewByteArray(
                                                       extraAudioDescriptor.descriptor_length));
        env->SetByteArrayRegion(jDescriptor.get(), 0, extraAudioDescriptor.descriptor_length,
                                reinterpret_cast<const jbyte *>(extraAudioDescriptor.descriptor));
        jAudioDescriptor =
                ScopedLocalRef<jobject>(env,
                                        env->NewObject(gAudioDescriptorClass, gAudiODescriptorCstor,
                                                       standard, encapsulationType,
                                                       jDescriptor.get()));
        env->CallBooleanMethod(jAudioDescriptors, gArrayListMethods.add, jAudioDescriptor.get());
    }

    // gains
    jGains = env->NewObjectArray(nAudioPort->num_gains,
                                          gAudioGainClass, NULL);
@@ -1365,7 +1415,7 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
        *jAudioPort =
                env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor, jHandle, jDeviceName,
                               jAudioProfiles, jGains, nAudioPort->ext.device.type, jAddress,
                               jEncapsulationModes, jEncapsulationMetadataTypes);
                               jEncapsulationModes, jEncapsulationMetadataTypes, jAudioDescriptors);
        env->DeleteLocalRef(jAddress);
    } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
        ALOGV("convertAudioPortFromNative is a mix");
@@ -1414,6 +1464,9 @@ exit:
    if (jAudioPortConfig != NULL) {
        env->DeleteLocalRef(jAudioPortConfig);
    }
    if (jAudioDescriptors != nullptr) {
        env->DeleteLocalRef(jAudioDescriptors);
    }

    return jStatus;
}
@@ -2790,7 +2843,8 @@ int register_android_media_AudioSystem(JNIEnv *env)
    gAudioDevicePortCstor =
            GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
                             "(Landroid/media/AudioHandle;Ljava/lang/String;Ljava/util/List;"
                             "[Landroid/media/AudioGain;ILjava/lang/String;[I[I)V");
                             "[Landroid/media/AudioGain;ILjava/lang/String;[I[I"
                             "Ljava/util/List;)V");

    // When access AudioPort as AudioDevicePort
    gAudioPortFields.mType = GetFieldIDOrDie(env, audioDevicePortClass, "mType", "I");
@@ -2909,7 +2963,11 @@ int register_android_media_AudioSystem(JNIEnv *env)

    jclass audioProfileClass = FindClassOrDie(env, "android/media/AudioProfile");
    gAudioProfileClass = MakeGlobalRefOrDie(env, audioProfileClass);
    gAudioProfileCstor = GetMethodIDOrDie(env, audioProfileClass, "<init>", "(I[I[I[I)V");
    gAudioProfileCstor = GetMethodIDOrDie(env, audioProfileClass, "<init>", "(I[I[I[II)V");

    jclass audioDescriptorClass = FindClassOrDie(env, "android/media/AudioDescriptor");
    gAudioDescriptorClass = MakeGlobalRefOrDie(env, audioDescriptorClass);
    gAudiODescriptorCstor = GetMethodIDOrDie(env, audioDescriptorClass, "<init>", "(II[B)V");

    AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback);

+90 −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.
 */

package android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * The AudioDescriptor contains the information to describe the audio playback/capture
 * capabilities. The capabilities are described by a byte array, which is defined by a
 * particular standard. This is used when the format is unrecognized to the platform.
 */
public class AudioDescriptor {
    /**
     * The audio standard is not specified.
     */
    public static final int STANDARD_NONE = 0;
    /**
     * The Extended Display Identification Data (EDID) standard for a short audio descriptor.
     */
    public static final int STANDARD_EDID = 1;

    /** @hide */
    @IntDef({
            STANDARD_NONE,
            STANDARD_EDID,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AudioDescriptorStandard {}

    private final int mStandard;
    private final byte[] mDescriptor;
    private final int mEncapsulationType;

    AudioDescriptor(int standard, int encapsulationType, @NonNull byte[] descriptor) {
        mStandard = standard;
        mEncapsulationType = encapsulationType;
        mDescriptor = descriptor;
    }

    /**
     * @return the standard that defines audio playback/capture capabilities.
     */
    public @AudioDescriptorStandard int getStandard() {
        return mStandard;
    }

    /**
     * @return a byte array that describes audio playback/capture capabilities as encoded by the
     * standard for this AudioDescriptor.
     */
    public @NonNull byte[] getDescriptor() {
        return mDescriptor;
    }

    /**
     * The encapsulation type indicates what encapsulation type is required when the framework is
     * using this extra audio descriptor for playing to a device exposing this audio profile.
     * When encapsulation is required, only playback with {@link android.media.AudioTrack} API is
     * supported. But playback with {@link android.media.MediaPlayer} is not.
     * When an encapsulation type is required, the {@link AudioFormat} encoding selected when
     * creating the {@link AudioTrack} must match the encapsulation type, e.g
     * AudioFormat#ENCODING_IEC61937 for AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937.
     *
     * @return an integer representing the encapsulation type
     *
     * @see AudioProfile#AUDIO_ENCAPSULATION_TYPE_NONE
     * @see AudioProfile#AUDIO_ENCAPSULATION_TYPE_IEC61937
     */
    public @AudioProfile.EncapsulationType int getEncapsulationType() {
        return mEncapsulationType;
    }
}
Loading