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

Commit 7ed22ff1 authored by jiabin's avatar jiabin
Browse files

Add APIs to query MMAP support in AAudio.

Bug: 367809497
Test: atest AAudioTests
Flag: EXEMPT NDK
Change-Id: I19df0f40d6151bba9cb0869876bb6ea3fef38d91
parent b2ec9c01
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ int main(int argc __unused, char **argv)
        // attempting to call audio flinger on a null pointer could make the process crash
        // and attract attentions.
        std::vector<AudioMMapPolicyInfo> policyInfos;
        status_t status = sp<IAudioFlinger>::cast(af)->getMmapPolicyInfos(
        status_t status = AudioSystem::getMmapPolicyInfos(
                AudioMMapPolicyType::DEFAULT, &policyInfos);
        // Initialize aaudio service when querying mmap policy succeeds and
        // any of the policy supports MMAP.
+205 −4
Original line number Diff line number Diff line
@@ -31,24 +31,225 @@ extern "C" {
 * They may change or be removed at any time.
 ************************************************************************************/

/**
 * When the audio is played/recorded via AAudio MMAP data path, the apps can write to/read from
 * a shared memory that will also be accessed directly by hardware. That reduces the audio latency.
 * The following values are used to describe how AAudio MMAP is supported.
 */
enum {
    /**
     * Related feature is disabled and never used.
     * AAudio MMAP is disabled and never used.
     */
    AAUDIO_POLICY_NEVER = 1,

    /**
     * If related feature works then use it. Otherwise fall back to something else.
     * AAudio MMAP support depends on device's availability. It will be used
     * when it is possible or fallback to the normal path, where the audio data
     * will be delivered via audio framework data pipeline.
     */
    AAUDIO_POLICY_AUTO,

    /**
     * Related feature must be used. If not available then fail.
     * AAudio MMAP must be used or fail.
     */
    AAUDIO_POLICY_ALWAYS
};
typedef int32_t aaudio_policy_t;

// The values are copied from JAVA SDK device types defined in android/media/AudioDeviceInfo.java
// When a new value is added, it should be added here and handled by the conversion at
// AAudioConvert_aaudioToAndroidDeviceType.
typedef enum AAudio_DeviceType : int32_t {
    /**
     * A device type describing the attached earphone speaker.
     */
    AAUDIO_DEVICE_BUILTIN_EARPIECE = 1,

    /**
     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
     * in a device.
     */
    AAUDIO_DEVICE_BUILTIN_SPEAKER = 2,

    /**
     * A device type describing a headset, which is the combination of a headphones and microphone.
     */
    AAUDIO_DEVICE_WIRED_HEADSET = 3,

    /**
     * A device type describing a pair of wired headphones.
     */
    AAUDIO_DEVICE_WIRED_HEADPHONES = 4,

    /**
     * A device type describing an analog line-level connection.
     */
    AAUDIO_DEVICE_LINE_ANALOG = 5,

    /**
     * A device type describing a digital line connection (e.g. SPDIF).
     */
    AAUDIO_DEVICE_LINE_DIGITAL = 6,

    /**
     * A device type describing a Bluetooth device typically used for telephony.
     */
    AAUDIO_DEVICE_BLUETOOTH_SCO = 7,

    /**
     * A device type describing a Bluetooth device supporting the A2DP profile.
     */
    AAUDIO_DEVICE_BLUETOOTH_A2DP = 8,

    /**
     * A device type describing an HDMI connection .
     */
    AAUDIO_DEVICE_HDMI = 9,

    /**
     * A device type describing the Audio Return Channel of an HDMI connection.
     */
    AAUDIO_DEVICE_HDMI_ARC = 10,

    /**
     * A device type describing a USB audio device.
     */
    AAUDIO_DEVICE_USB_DEVICE = 11,

    /**
     * A device type describing a USB audio device in accessory mode.
     */
    AAUDIO_DEVICE_USB_ACCESSORY = 12,

    /**
     * A device type describing the audio device associated with a dock.
     * Starting at API 34, this device type only represents digital docks, while docks with an
     * analog connection are represented with {@link #AAUDIO_DEVICE_DOCK_ANALOG}.
     */
    AAUDIO_DEVICE_DOCK = 13,

    /**
     * A device type associated with the transmission of audio signals over FM.
     */
    AAUDIO_DEVICE_FM = 14,

    /**
     * A device type describing the microphone(s) built in a device.
     */
    AAUDIO_DEVICE_BUILTIN_MIC = 15,

    /**
     * A device type for accessing the audio content transmitted over FM.
     */
    AAUDIO_DEVICE_FM_TUNER = 16,

    /**
     * A device type for accessing the audio content transmitted over the TV tuner system.
     */
    AAUDIO_DEVICE_TV_TUNER = 17,

    /**
     * A device type describing the transmission of audio signals over the telephony network.
     */
    AAUDIO_DEVICE_TELEPHONY = 18,

    /**
     * A device type describing the auxiliary line-level connectors.
     */
    AAUDIO_DEVICE_AUX_LINE = 19,

    /**
     * A device type connected over IP.
     */
    AAUDIO_DEVICE_IP = 20,

    /**
     * A type-agnostic device used for communication with external audio systems.
     */
    AAUDIO_DEVICE_BUS = 21,

    /**
     * A device type describing a USB audio headset.
     */
    AAUDIO_DEVICE_USB_HEADSET = 22,

    /**
     * A device type describing a Hearing Aid.
     */
    AAUDIO_DEVICE_HEARING_AID = 23,

    /**
     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
     * in a device, that is specifically tuned for outputting sounds like notifications and alarms
     * (i.e. sounds the user couldn't necessarily anticipate).
     * <p>Note that this physical audio device may be the same as {@link #TYPE_BUILTIN_SPEAKER}
     * but is driven differently to safely accommodate the different use case.</p>
     */
    AAUDIO_DEVICE_BUILTIN_SPEAKER_SAFE = 24,

    /**
     * A device type for rerouting audio within the Android framework between mixes and
     * system applications.
     */
    AAUDIO_DEVICE_REMOTE_SUBMIX = 25,
    /**
     * A device type describing a Bluetooth Low Energy (BLE) audio headset or headphones.
     * Headphones are grouped with headsets when the device is a sink:
     * the features of headsets and headphones with regard to playback are the same.
     */
    AAUDIO_DEVICE_BLE_HEADSET = 26,

    /**
     * A device type describing a Bluetooth Low Energy (BLE) audio speaker.
     */
    AAUDIO_DEVICE_BLE_SPEAKER = 27,

    /**
     * A device type describing an Echo Canceller loopback Reference.
     * This device is only used when capturing with MediaRecorder.AudioSource.ECHO_REFERENCE,
     * which requires privileged permission
     * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT}.
     *
     * Note that this is not exposed as it is a system API that requires privileged permission.
     */
    // AAUDIO_DEVICE_ECHO_REFERENCE = 28,

    /**
     * A device type describing the Enhanced Audio Return Channel of an HDMI connection.
     */
    AAUDIO_DEVICE_HDMI_EARC = 29,

    /**
     * A device type describing a Bluetooth Low Energy (BLE) broadcast group.
     */
    AAUDIO_DEVICE_BLE_BROADCAST = 30,

    /**
     * A device type describing the audio device associated with a dock using an analog connection.
     */
    AAUDIO_DEVICE_DOCK_ANALOG = 31
} AAudio_DeviceType;

/**
 * Query how aaudio mmap is supported for the given device type.
 *
 * @param device device type
 * @param direction {@link AAUDIO_DIRECTION_OUTPUT} or {@link AAUDIO_DIRECTION_INPUT}
 * @return the mmap policy or negative error
 */
AAUDIO_API aaudio_policy_t AAudio_getPlatformMMapPolicy(
        AAudio_DeviceType device, aaudio_direction_t direction) __INTRODUCED_IN(36);

/**
 * Query how aaudio exclusive mmap is supported for the given device type.
 *
 * @param device device type
 * @param direction {@link AAUDIO_DIRECTION_OUTPUT} or {@link AAUDIO_DIRECTION_INPUT}
 * @return the mmap exclusive policy or negative error
 */
AAUDIO_API aaudio_policy_t AAudio_getPlatformMMapExclusivePolicy(
        AAudio_DeviceType device, aaudio_direction_t direction) __INTRODUCED_IN(36);

/**
 * Control whether AAudioStreamBuilder_openStream() will use the new MMAP data path
 * or the older "Legacy" data path.
+10 −0
Original line number Diff line number Diff line
@@ -53,6 +53,16 @@ AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t st
    return AudioGlobal_convertStreamStateToText(state);
}

AAUDIO_API aaudio_policy_t AAudio_getPlatformMMapPolicy(
        AAudio_DeviceType device, aaudio_direction_t direction) {
    return AudioGlobal_getPlatformMMapPolicy(device, direction);
}

AAUDIO_API aaudio_policy_t AAudio_getPlatformMMapExclusivePolicy(
        AAudio_DeviceType device, aaudio_direction_t direction) {
    return AudioGlobal_getPlatformMMapExclusivePolicy(device, direction);
}

static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
{
    return (AudioStream*) stream;
+44 −0
Original line number Diff line number Diff line
@@ -15,6 +15,13 @@
 */
#include <aaudio/AAudio.h>
#include <aaudio/AAudioTesting.h>
#include <android/media/audio/common/AudioDevice.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AudioSystem.h>
#include <system/audio-hal-enums.h>
#include <utility/AAudioUtilities.h>

#include "AudioGlobal.h"

@@ -23,6 +30,10 @@
 */
namespace aaudio {

using android::media::audio::common::AudioDevice;
using android::media::audio::common::AudioMMapPolicyInfo;
using android::media::audio::common::AudioMMapPolicyType;

static aaudio_policy_t g_MMapPolicy = AAUDIO_UNSPECIFIED;

aaudio_policy_t AudioGlobal_getMMapPolicy() {
@@ -132,6 +143,39 @@ const char* AudioGlobal_convertStreamStateToText(aaudio_stream_state_t state) {
    return "Unrecognized";
}

namespace {

aaudio_policy_t getPlatformMMapPolicy(AudioMMapPolicyType policyType, AAudio_DeviceType device,
                                      aaudio_direction_t direction) {
    if (direction != AAUDIO_DIRECTION_INPUT && direction != AAUDIO_DIRECTION_OUTPUT) {
        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
    }
    const audio_devices_t deviceType = AAudioConvert_aaudioToAndroidDeviceType(device, direction);
    if (deviceType == AUDIO_DEVICE_NONE) {
        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
    }

    AudioMMapPolicyInfo policyInfo;
    if (android::status_t status = android::AudioSystem::getMmapPolicyForDevice(
            policyType, deviceType, &policyInfo);
        status != android::NO_ERROR) {
        return AAudioConvert_androidToAAudioResult(status);
    }
    return AAudioConvert_androidToAAudioMMapPolicy(policyInfo.mmapPolicy);
}

} // namespace

aaudio_policy_t AudioGlobal_getPlatformMMapPolicy(
        AAudio_DeviceType device, aaudio_direction_t direction) {
    return getPlatformMMapPolicy(AudioMMapPolicyType::DEFAULT, device, direction);
}

aaudio_policy_t AudioGlobal_getPlatformMMapExclusivePolicy(
        AAudio_DeviceType device, aaudio_direction_t direction) {
    return getPlatformMMapPolicy(AudioMMapPolicyType::EXCLUSIVE, device, direction);
}

#undef AAUDIO_CASE_ENUM

}  // namespace aaudio
+5 −0
Original line number Diff line number Diff line
@@ -40,6 +40,11 @@ const char* AudioGlobal_convertResultToText(aaudio_result_t returnCode);
const char* AudioGlobal_convertSharingModeToText(aaudio_sharing_mode_t mode);
const char* AudioGlobal_convertStreamStateToText(aaudio_stream_state_t state);

aaudio_policy_t AudioGlobal_getPlatformMMapPolicy(
        AAudio_DeviceType device, aaudio_direction_t direction);
aaudio_policy_t AudioGlobal_getPlatformMMapExclusivePolicy(
        AAudio_DeviceType device, aaudio_direction_t direction);

} // namespace aaudio

#endif  // AAUDIO_AUDIOGLOBAL_H
Loading