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/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"