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

Commit 4a341867 authored by jiabin's avatar jiabin
Browse files

Add test to verify if MMAP path is used or not.

Bug: 243718858
Test: atest aaudio_test_mmap_path
Change-Id: Iff09f6f3a2ef89e7e8b6bd0531fd429a76c7c866
parent 0f9c1a8a
Loading
Loading
Loading
Loading
+3 −35
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@

#include <aaudio/AAudio.h>
#include <aaudio/AAudioTesting.h>
#include <android/media/audio/common/AudioMMapPolicy.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <media/AudioSystem.h>
@@ -37,10 +36,10 @@
#include "core/AudioStreamBuilder.h"
#include "legacy/AudioStreamRecord.h"
#include "legacy/AudioStreamTrack.h"
#include "utility/AAudioUtilities.h"

using namespace aaudio;

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

@@ -95,37 +94,6 @@ static aaudio_result_t builder_createStream(aaudio_direction_t direction,
    return result;
}

namespace {

aaudio_policy_t aidl2legacy_aaudio_policy(AudioMMapPolicy aidl) {
    switch (aidl) {
        case AudioMMapPolicy::NEVER:
            return AAUDIO_POLICY_NEVER;
        case AudioMMapPolicy::AUTO:
            return AAUDIO_POLICY_AUTO;
        case AudioMMapPolicy::ALWAYS:
            return AAUDIO_POLICY_ALWAYS;
        case AudioMMapPolicy::UNSPECIFIED:
        default:
            return AAUDIO_UNSPECIFIED;
    }
}

// The aaudio policy will be ALWAYS, NEVER, UNSPECIFIED only when all policy info are
// ALWAYS, NEVER or UNSPECIFIED. Otherwise, the aaudio policy will be AUTO.
aaudio_policy_t getAAudioPolicy(
        const std::vector<AudioMMapPolicyInfo>& policyInfos) {
    if (policyInfos.empty()) return AAUDIO_POLICY_AUTO;
    for (size_t i = 1; i < policyInfos.size(); ++i) {
        if (policyInfos.at(i).mmapPolicy != policyInfos.at(0).mmapPolicy) {
            return AAUDIO_POLICY_AUTO;
        }
    }
    return aidl2legacy_aaudio_policy(policyInfos.at(0).mmapPolicy);
}

} // namespace

// Try to open using MMAP path if that is allowed.
// Fall back to Legacy path if MMAP not available.
// Exact behavior is controlled by MMapPolicy.
@@ -150,7 +118,7 @@ aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
    // If not specified then get from a system property.
    if (mmapPolicy == AAUDIO_UNSPECIFIED && android::AudioSystem::getMmapPolicyInfo(
                AudioMMapPolicyType::DEFAULT, &policyInfos) == NO_ERROR) {
        mmapPolicy = getAAudioPolicy(policyInfos);
        mmapPolicy = AAudio_getAAudioPolicy(policyInfos);
    }
    // If still not specified then use the default.
    if (mmapPolicy == AAUDIO_UNSPECIFIED) {
@@ -161,7 +129,7 @@ aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
    aaudio_policy_t mmapExclusivePolicy = AAUDIO_UNSPECIFIED;
    if (android::AudioSystem::getMmapPolicyInfo(
            AudioMMapPolicyType::EXCLUSIVE, &policyInfos) == NO_ERROR) {
        mmapExclusivePolicy = getAAudioPolicy(policyInfos);
        mmapExclusivePolicy = AAudio_getAAudioPolicy(policyInfos);
    }
    if (mmapExclusivePolicy == AAUDIO_UNSPECIFIED) {
        mmapExclusivePolicy = AAUDIO_MMAP_EXCLUSIVE_POLICY_DEFAULT;
+39 −7
Original line number Diff line number Diff line
@@ -16,24 +16,28 @@

#define LOG_TAG "AAudio"
//#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <cutils/properties.h>
#include <assert.h>
#include <math.h>
#include <stdint.h>

#include <aaudio/AAudioTesting.h>
#include <android/media/audio/common/AudioMMapPolicy.h>
#include <cutils/properties.h>
#include <sys/types.h>
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/Log.h>

#include "aaudio/AAudio.h"
#include "core/AudioGlobal.h"
#include <aaudio/AAudioTesting.h>
#include <math.h>
#include <system/audio.h>
#include <assert.h>

#include "utility/AAudioUtilities.h"

using namespace android;

using android::media::audio::common::AudioMMapPolicy;
using android::media::audio::common::AudioMMapPolicyInfo;

status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
    // This covers the case for AAUDIO_OK and for positive results.
    if (result >= 0) {
@@ -638,3 +642,31 @@ aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) {
    }
    return result;
}

namespace {

aaudio_policy_t aidl2legacy_aaudio_policy(AudioMMapPolicy aidl) {
    switch (aidl) {
        case AudioMMapPolicy::NEVER:
            return AAUDIO_POLICY_NEVER;
        case AudioMMapPolicy::AUTO:
            return AAUDIO_POLICY_AUTO;
        case AudioMMapPolicy::ALWAYS:
            return AAUDIO_POLICY_ALWAYS;
        case AudioMMapPolicy::UNSPECIFIED:
        default:
            return AAUDIO_UNSPECIFIED;
    }
}

} // namespace

aaudio_policy_t AAudio_getAAudioPolicy(const std::vector<AudioMMapPolicyInfo>& policyInfos) {
    if (policyInfos.empty()) return AAUDIO_POLICY_AUTO;
    for (size_t i = 1; i < policyInfos.size(); ++i) {
        if (policyInfos.at(i).mmapPolicy != policyInfos.at(0).mmapPolicy) {
            return AAUDIO_POLICY_AUTO;
        }
    }
    return aidl2legacy_aaudio_policy(policyInfos.at(0).mmapPolicy);
}
+8 −0
Original line number Diff line number Diff line
@@ -19,14 +19,17 @@

#include <algorithm>
#include <functional>
#include <vector>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>

#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <utils/Errors.h>
#include <system/audio.h>

#include "aaudio/AAudio.h"
#include "aaudio/AAudioTesting.h"

/**
 * Convert an AAudio result into the closest matching Android status.
@@ -343,4 +346,9 @@ enum {
    AAUDIO_CHANNEL_INDEX_MASK_24 = AAUDIO_CHANNEL_BIT_INDEX | (1 << 24) - 1,
};

// The aaudio policy will be ALWAYS, NEVER, UNSPECIFIED only when all policy info are
// ALWAYS, NEVER or UNSPECIFIED. Otherwise, the aaudio policy will be AUTO.
aaudio_policy_t AAudio_getAAudioPolicy(
        const std::vector<android::media::audio::common::AudioMMapPolicyInfo>& policyInfos);

#endif //UTILITY_AAUDIO_UTILITIES_H
+14 −0
Original line number Diff line number Diff line
@@ -214,3 +214,17 @@ cc_binary {
    srcs: ["test_disconnect_race.cpp"],
    shared_libs: ["libaaudio"],
}

cc_test {
    name: "aaudio_test_mmap_path",
    defaults: [
        "libaaudio_tests_defaults",
    ],
    srcs: ["test_mmap_path.cpp"],
    shared_libs: [
        "libaaudio",
        "libaaudio_internal",
        "libaudioclient",
        "liblog",
    ],
}
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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 "test_mmap_path"

#include <vector>

#include <aaudio/AAudio.h>
#include <aaudio/AAudioTesting.h>
#include <android/log.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <media/AudioSystem.h>

#include <gtest/gtest.h>

#include "utility/AAudioUtilities.h"

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

/**
 * Open a stream via AAudio API and set the performance mode as LOW_LATENCY. When MMAP is supported,
 * the stream is supposed to be on MMAP path instead of legacy path. This is guaranteed on pixel
 * devices, but may not be guaranteed on other vendor devices.
 * @param direction the direction for the stream
 */
static void openStreamAndVerify(aaudio_direction_t direction) {
    std::vector<AudioMMapPolicyInfo> policyInfos;
    ASSERT_EQ(android::NO_ERROR, android::AudioSystem::getMmapPolicyInfo(
            AudioMMapPolicyType::DEFAULT, &policyInfos));
    if (AAudio_getAAudioPolicy(policyInfos) == AAUDIO_POLICY_NEVER) {
        // Query the system MMAP policy, if it is NEVER, it indicates there is no MMAP support.
        // In that case, there is no need to run the test. The reason of adding the query is to
        // avoid someone accidentally run the test on device that doesn't support MMAP,
        // such as cuttlefish.
        ALOGD("Skip test as mmap is not supported");
        return;
    }

    AAudioStreamBuilder *aaudioBuilder = nullptr;
    AAudioStream *aaudioStream = nullptr;

    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));

    AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);

    EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
    EXPECT_EQ(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, AAudioStream_getPerformanceMode(aaudioStream));
    EXPECT_TRUE(AAudioStream_isMMapUsed(aaudioStream));

    AAudioStream_close(aaudioStream);
    AAudioStreamBuilder_delete(aaudioBuilder);
}

TEST(test_mmap_path, input) {
    openStreamAndVerify(AAUDIO_DIRECTION_INPUT);
}

TEST(test_mmap_path, output) {
    openStreamAndVerify(AAUDIO_DIRECTION_OUTPUT);
}