aaudio: AAudio_setMMapPolicy()
Controls whether MMAP data path is used NEVER, AUTO or ALWAYS
For testing only. To improve code coverage in CTS.
Bug: 38268547
Test: write_sine.cpp
Change-Id: Iad97876fb6f1d0c653262161b7b5519d83d16ac5
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 27c6128..4cf5ef5 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -20,15 +20,22 @@
#include <stdlib.h>
#include <math.h>
#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
#include "AAudioExampleUtils.h"
#include "AAudioSimplePlayer.h"
#define SAMPLE_RATE 48000
#define NUM_SECONDS 20
-#define REQUESTED_FORMAT AAUDIO_FORMAT_PCM_I16
-#define REQUESTED_SHARING_MODE AAUDIO_SHARING_MODE_SHARED
-//#define REQUESTED_SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE
+#define MMAP_POLICY AAUDIO_UNSPECIFIED
+//#define MMAP_POLICY AAUDIO_POLICY_NEVER
+//#define MMAP_POLICY AAUDIO_POLICY_AUTO
+//#define MMAP_POLICY AAUDIO_POLICY_ALWAYS
+
+#define REQUESTED_FORMAT AAUDIO_FORMAT_PCM_I16
+
+#define REQUESTED_SHARING_MODE AAUDIO_SHARING_MODE_SHARED
+//#define REQUESTED_SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE
int main(int argc, char **argv)
@@ -64,6 +71,9 @@
printf("%s - Play a sine wave using AAudio\n", argv[0]);
+ AAudio_setMMapPolicy(MMAP_POLICY);
+ printf("requested MMapPolicy = %d\n", AAudio_getMMapPolicy());
+
player.setSharingMode(REQUESTED_SHARING_MODE);
result = player.open(requestedChannelCount, requestedSampleRate, requestedDataFormat,
@@ -98,7 +108,7 @@
// This is the number of frames that are read in one chunk by a DMA controller
// or a DSP or a mixer.
framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
- printf("Buffer: bufferSize = %d\n", AAudioStream_getBufferSizeInFrames(aaudioStream));
+ printf("Buffer: bufferSize = %d\n", AAudioStream_getBufferSizeInFrames(aaudioStream));
bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
printf("Buffer: bufferCapacity = %d, remainder = %d\n",
bufferCapacity, bufferCapacity % framesPerBurst);
@@ -112,11 +122,12 @@
printf("Buffer: framesPerBurst = %d\n",framesPerBurst);
printf("Buffer: framesPerWrite = %d\n",framesPerWrite);
- actualDataFormat = AAudioStream_getFormat(aaudioStream);
- printf("DataFormat: requested = %d, actual = %d\n", REQUESTED_FORMAT, actualDataFormat);
- // TODO handle other data formats
+ printf("PerformanceMode = %d\n", AAudioStream_getPerformanceMode(aaudioStream));
+ printf("is MMAP used? = %s\n", AAudioStream_isMMapUsed(aaudioStream) ? "yes" : "no");
- printf("PerformanceMode: %d\n", AAudioStream_getPerformanceMode(aaudioStream));
+ actualDataFormat = AAudioStream_getFormat(aaudioStream);
+ printf("DataFormat: requested = %d, actual = %d\n", REQUESTED_FORMAT, actualDataFormat);
+ // TODO handle other data formats
// Allocate a buffer for the audio data.
if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) {
diff --git a/media/libaaudio/include/aaudio/AAudioTesting.h b/media/libaaudio/include/aaudio/AAudioTesting.h
new file mode 100644
index 0000000..02ec411
--- /dev/null
+++ b/media/libaaudio/include/aaudio/AAudioTesting.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/**
+ * This is test support for AAudio.
+ */
+#ifndef AAUDIO_AAUDIO_TESTING_H
+#define AAUDIO_AAUDIO_TESTING_H
+
+#include <aaudio/AAudio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************************************************************************
+ * The definitions below are only for testing. Do not use them in an application.
+ * They may change or be removed at any time.
+ ************************************************************************************/
+
+enum {
+ /**
+ * Related feature is disabled and never used.
+ */
+ AAUDIO_POLICY_NEVER = 1,
+
+ /**
+ * If related feature works then use it. Otherwise fall back to something else.
+ */
+ AAUDIO_POLICY_AUTO,
+
+ /**
+ * Related feature must be used. If not available then fail.
+ */
+ AAUDIO_POLICY_ALWAYS
+};
+typedef int32_t aaudio_policy_t;
+
+/**
+ * Control whether AAudioStreamBuilder_openStream() will use the new MMAP data path
+ * or the older "Legacy" data path.
+ *
+ * This will only affect the current process.
+ *
+ * If unspecified then the policy will be based on system properties or configuration.
+ *
+ * @note This is only for testing. Do not use this in an application.
+ * It may change or be removed at any time.
+ *
+ * @param policy AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER, AAUDIO_POLICY_AUTO, or AAUDIO_POLICY_ALWAYS
+ * @return AAUDIO_OK or a negative error
+ */
+AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy);
+
+/**
+ * Get the current MMAP policy set by AAudio_setMMapPolicy().
+ *
+ * @note This is only for testing. Do not use this in an application.
+ * It may change or be removed at any time.
+ *
+ * @return current policy
+ */
+AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy();
+
+/**
+ * Return true if the stream uses the MMAP data path versus the legacy path.
+ *
+ * @note This is only for testing. Do not use this in an application.
+ * It may change or be removed at any time.
+ *
+ * @return true if the stream uses ther MMAP data path
+ */
+AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //AAUDIO_AAUDIO_TESTING_H
+
+/** @} */
diff --git a/media/libaaudio/libaaudio.map.txt b/media/libaaudio/libaaudio.map.txt
index 8f74800..2ba5250 100644
--- a/media/libaaudio/libaaudio.map.txt
+++ b/media/libaaudio/libaaudio.map.txt
@@ -3,6 +3,8 @@
AAudio_convertResultToText;
AAudio_convertStreamStateToText;
AAudio_createStreamBuilder;
+ AAudio_getMMapPolicy;
+ AAudio_setMMapPolicy;
AAudioStreamBuilder_setPerformanceMode;
AAudioStreamBuilder_setDeviceId;
AAudioStreamBuilder_setDataCallback;
@@ -43,6 +45,7 @@
AAudioStream_getFramesWritten;
AAudioStream_getFramesRead;
AAudioStream_getTimestamp;
+ AAudioStream_isMMapUsed;
local:
*;
};
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index c644ee5..d22ad32 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -22,6 +22,7 @@
#include <pthread.h>
#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
#include "AudioStreamBuilder.h"
#include "AudioStream.h"
@@ -94,6 +95,13 @@
#undef AAUDIO_CASE_ENUM
+
+/******************************************
+ * Static globals.
+ */
+static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED;
+
+
static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
{
return (AudioStream*) stream;
@@ -454,3 +462,29 @@
return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds);
}
+
+AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() {
+ return s_MMapPolicy;
+}
+
+AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) {
+ aaudio_result_t result = AAUDIO_OK;
+ switch(policy) {
+ case AAUDIO_UNSPECIFIED:
+ case AAUDIO_POLICY_NEVER:
+ case AAUDIO_POLICY_AUTO:
+ case AAUDIO_POLICY_ALWAYS:
+ s_MMapPolicy = policy;
+ break;
+ default:
+ result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ break;
+ }
+ return result;
+}
+
+AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->isMMap();
+}
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index e6d5d74..4262f27 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -22,6 +22,7 @@
#include <stdint.h>
#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
#include "binding/AAudioBinderClient.h"
#include "client/AudioStreamInternalCapture.h"
@@ -33,6 +34,9 @@
using namespace aaudio;
+#define AAUDIO_MMAP_POLICY_DEFAULT AAUDIO_POLICY_NEVER
+#define AAUDIO_MMAP_EXCLUSIVE_POLICY_DEFAULT AAUDIO_POLICY_NEVER
+
/*
* AudioStreamBuilder
*/
@@ -76,25 +80,41 @@
return result;
}
-// Try to open using MMAP path if that is enabled.
-// Fall back to Legacy path is MMAP not available.
+// 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.
aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
AudioStream *audioStream = nullptr;
*streamPtr = nullptr;
- int32_t mmapEnabled = AAudioProperty_getMMapEnabled();
- int32_t mmapExclusiveEnabled = AAudioProperty_getMMapExclusiveEnabled();
+ // The API setting is the highest priority.
+ aaudio_policy_t mmapPolicy = AAudio_getMMapPolicy();
+ // If not specified then get from a system property.
+ if (mmapPolicy == AAUDIO_UNSPECIFIED) {
+ mmapPolicy = AAudioProperty_getMMapPolicy();
+ }
+ // If still not specified then use the default.
+ if (mmapPolicy == AAUDIO_UNSPECIFIED) {
+ mmapPolicy = AAUDIO_MMAP_POLICY_DEFAULT;
+ }
+
+ int32_t mapExclusivePolicy = AAudioProperty_getMMapExclusivePolicy();
+ if (mapExclusivePolicy == AAUDIO_UNSPECIFIED) {
+ mapExclusivePolicy = AAUDIO_MMAP_EXCLUSIVE_POLICY_DEFAULT;
+ }
+ ALOGD("AudioStreamBuilder(): mmapPolicy = %d, mapExclusivePolicy = %d",
+ mmapPolicy, mapExclusivePolicy);
aaudio_sharing_mode_t sharingMode = getSharingMode();
if ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE)
- && (mmapExclusiveEnabled == AAUDIO_USE_NEVER)) {
+ && (mapExclusivePolicy == AAUDIO_POLICY_NEVER)) {
ALOGW("AudioStreamBuilder(): EXCLUSIVE sharing mode not supported. Use SHARED.");
sharingMode = AAUDIO_SHARING_MODE_SHARED;
setSharingMode(sharingMode);
}
- bool allowMMap = mmapEnabled != AAUDIO_USE_NEVER;
- bool allowLegacy = mmapEnabled != AAUDIO_USE_ALWAYS;
+ bool allowMMap = mmapPolicy != AAUDIO_POLICY_NEVER;
+ bool allowLegacy = mmapPolicy != AAUDIO_POLICY_ALWAYS;
aaudio_result_t result = builder_createStream(getDirection(), sharingMode,
allowMMap, &audioStream);
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 38ad59f..3fbcae9 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -24,7 +24,9 @@
#include <utils/Errors.h>
#include "aaudio/AAudio.h"
-#include "AAudioUtilities.h"
+#include <aaudio/AAudioTesting.h>
+
+#include "utility/AAudioUtilities.h"
using namespace android;
@@ -329,9 +331,10 @@
const char * caller) {
int32_t prop = property_get_int32(propName, defaultValue);
switch (prop) {
- case AAUDIO_USE_NEVER:
- case AAUDIO_USE_ALWAYS:
- case AAUDIO_USE_AUTO:
+ case AAUDIO_UNSPECIFIED:
+ case AAUDIO_POLICY_NEVER:
+ case AAUDIO_POLICY_ALWAYS:
+ case AAUDIO_POLICY_AUTO:
break;
default:
ALOGE("%s: invalid = %d", caller, prop);
@@ -341,14 +344,14 @@
return prop;
}
-int32_t AAudioProperty_getMMapEnabled() {
- return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_ENABLED,
- AAUDIO_USE_NEVER, __func__);
+int32_t AAudioProperty_getMMapPolicy() {
+ return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_POLICY,
+ AAUDIO_UNSPECIFIED, __func__);
}
-int32_t AAudioProperty_getMMapExclusiveEnabled() {
- return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_ENABLED,
- AAUDIO_USE_NEVER, __func__);
+int32_t AAudioProperty_getMMapExclusivePolicy() {
+ return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY,
+ AAUDIO_UNSPECIFIED, __func__);
}
int32_t AAudioProperty_getMixerBursts() {
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index 7c383c7..7039ba2 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -173,30 +173,21 @@
// Note that this code may be replaced by Settings or by some other system configuration tool.
-enum : int32_t {
- // Related feature is disabled
- AAUDIO_USE_NEVER = 0,
- // If related feature works then use it. Otherwise fall back to something else.
- AAUDIO_USE_AUTO = 1,
- // Related feature must be used. If not available then fail.
- AAUDIO_USE_ALWAYS = 2
-};
-
-#define AAUDIO_PROP_MMAP_ENABLED "aaudio.mmap_enabled"
+#define AAUDIO_PROP_MMAP_POLICY "aaudio.mmap_policy"
/**
* Read system property.
- * @return AAUDIO_USE_NEVER or AAUDIO_USE_AUTO or AAUDIO_USE_ALWAYS
+ * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
*/
-int32_t AAudioProperty_getMMapEnabled();
+int32_t AAudioProperty_getMMapPolicy();
-#define AAUDIO_PROP_MMAP_EXCLUSIVE_ENABLED "aaudio.mmap_exclusive_enabled"
+#define AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY "aaudio.mmap_exclusive_policy"
/**
* Read system property.
- * @return AAUDIO_USE_NEVER or AAUDIO_USE_AUTO or AAUDIO_USE_ALWAYS
+ * @return AAUDIO_UNSPECIFIED, AAUDIO_POLICY_NEVER or AAUDIO_POLICY_AUTO or AAUDIO_POLICY_ALWAYS
*/
-int32_t AAudioProperty_getMMapExclusiveEnabled();
+int32_t AAudioProperty_getMMapExclusivePolicy();
#define AAUDIO_PROP_MIXER_BURSTS "aaudio.mixer_bursts"