Add test to verify if MMAP path is used or not.
Bug: 243718858
Test: atest aaudio_test_mmap_path
Change-Id: Iff09f6f3a2ef89e7e8b6bd0531fd429a76c7c866
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 04b4325..91fd5bf 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -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 @@
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 @@
// 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_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;
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index a197ced..0afa11b 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -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 @@
}
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);
+}
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index b59ce1c..ac75306 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -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 @@
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
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 4b45909..438be0a 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -214,3 +214,17 @@
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",
+ ],
+}
diff --git a/media/libaaudio/tests/test_mmap_path.cpp b/media/libaaudio/tests/test_mmap_path.cpp
new file mode 100644
index 0000000..c8376f6
--- /dev/null
+++ b/media/libaaudio/tests/test_mmap_path.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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);
+}