Add aaudio APC opt-out

The opt-out was only present in the java API but not on the native ones.

Test: atest test_attributes
Change-Id: I1b84f1a428508e00de65e615b59405b9ee2ba009
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index 3d1bc9b..a987fab 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -62,6 +62,8 @@
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32((int32_t) getInputPreset());
     if (status != NO_ERROR) goto error;
+    status = parcel->writeInt32((int32_t) getAllowedCapturePolicy());
+    if (status != NO_ERROR) goto error;
     status = parcel->writeInt32(getSessionId());
     if (status != NO_ERROR) goto error;
     return NO_ERROR;
@@ -105,6 +107,9 @@
     setInputPreset((aaudio_input_preset_t) value);
     status = parcel->readInt32(&value);
     if (status != NO_ERROR) goto error;
+    setAllowedCapturePolicy((aaudio_allowed_capture_policy_t) value);
+    status = parcel->readInt32(&value);
+    if (status != NO_ERROR) goto error;
     setSessionId(value);
 
     return NO_ERROR;
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 0d71efc..8ae2644 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -204,6 +204,12 @@
     streamBuilder->setBufferCapacity(frames);
 }
 
+AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(
+        AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t policy) {
+    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+    streamBuilder->setAllowedCapturePolicy(policy);
+}
+
 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
                                                  aaudio_session_id_t sessionId)
 {
@@ -494,6 +500,13 @@
     return audioStream->getInputPreset();
 }
 
+AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
+        AAudioStream* stream)
+{
+    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+    return audioStream->getAllowedCapturePolicy();
+}
+
 AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 88da53a..e5bda30 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -35,17 +35,18 @@
 AAudioStreamParameters::~AAudioStreamParameters() {}
 
 void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
-    mSamplesPerFrame = other.mSamplesPerFrame;
-    mSampleRate      = other.mSampleRate;
-    mDeviceId        = other.mDeviceId;
-    mSessionId       = other.mSessionId;
-    mSharingMode     = other.mSharingMode;
-    mAudioFormat     = other.mAudioFormat;
-    mDirection       = other.mDirection;
-    mBufferCapacity  = other.mBufferCapacity;
-    mUsage           = other.mUsage;
-    mContentType     = other.mContentType;
-    mInputPreset     = other.mInputPreset;
+    mSamplesPerFrame      = other.mSamplesPerFrame;
+    mSampleRate           = other.mSampleRate;
+    mDeviceId             = other.mDeviceId;
+    mSessionId            = other.mSessionId;
+    mSharingMode          = other.mSharingMode;
+    mAudioFormat          = other.mAudioFormat;
+    mDirection            = other.mDirection;
+    mBufferCapacity       = other.mBufferCapacity;
+    mUsage                = other.mUsage;
+    mContentType          = other.mContentType;
+    mInputPreset          = other.mInputPreset;
+    mAllowedCapturePolicy = other.mAllowedCapturePolicy;
 }
 
 static aaudio_result_t isFormatValid(audio_format_t format) {
@@ -166,19 +167,32 @@
             // break;
     }
 
+    switch (mAllowedCapturePolicy) {
+        case AAUDIO_UNSPECIFIED:
+        case AAUDIO_ALLOW_CAPTURE_BY_ALL:
+        case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
+        case AAUDIO_ALLOW_CAPTURE_BY_NONE:
+            break; // valid
+        default:
+            ALOGE("allowed capture policy not valid = %d", mAllowedCapturePolicy);
+            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+            // break;
+    }
+
     return AAUDIO_OK;
 }
 
 void AAudioStreamParameters::dump() const {
-    ALOGD("mDeviceId        = %6d", mDeviceId);
-    ALOGD("mSessionId       = %6d", mSessionId);
-    ALOGD("mSampleRate      = %6d", mSampleRate);
-    ALOGD("mSamplesPerFrame = %6d", mSamplesPerFrame);
-    ALOGD("mSharingMode     = %6d", (int)mSharingMode);
-    ALOGD("mAudioFormat     = %6d", (int)mAudioFormat);
-    ALOGD("mDirection       = %6d", mDirection);
-    ALOGD("mBufferCapacity  = %6d", mBufferCapacity);
-    ALOGD("mUsage           = %6d", mUsage);
-    ALOGD("mContentType     = %6d", mContentType);
-    ALOGD("mInputPreset     = %6d", mInputPreset);
+    ALOGD("mDeviceId             = %6d", mDeviceId);
+    ALOGD("mSessionId            = %6d", mSessionId);
+    ALOGD("mSampleRate           = %6d", mSampleRate);
+    ALOGD("mSamplesPerFrame      = %6d", mSamplesPerFrame);
+    ALOGD("mSharingMode          = %6d", (int)mSharingMode);
+    ALOGD("mAudioFormat          = %6d", (int)mAudioFormat);
+    ALOGD("mDirection            = %6d", mDirection);
+    ALOGD("mBufferCapacity       = %6d", mBufferCapacity);
+    ALOGD("mUsage                = %6d", mUsage);
+    ALOGD("mContentType          = %6d", mContentType);
+    ALOGD("mInputPreset          = %6d", mInputPreset);
+    ALOGD("mAllowedCapturePolicy = %6d", mAllowedCapturePolicy);
 }
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index 6beb4b2..2e21a8d 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -112,6 +112,14 @@
         mInputPreset = inputPreset;
     }
 
+    aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
+        return mAllowedCapturePolicy;
+    }
+
+    void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
+        mAllowedCapturePolicy = policy;
+    }
+
     aaudio_session_id_t getSessionId() const {
         return mSessionId;
     }
@@ -138,17 +146,18 @@
     void dump() const;
 
 private:
-    int32_t                    mSamplesPerFrame = AAUDIO_UNSPECIFIED;
-    int32_t                    mSampleRate      = AAUDIO_UNSPECIFIED;
-    int32_t                    mDeviceId        = AAUDIO_UNSPECIFIED;
-    aaudio_sharing_mode_t      mSharingMode     = AAUDIO_SHARING_MODE_SHARED;
-    audio_format_t             mAudioFormat     = AUDIO_FORMAT_DEFAULT;
-    aaudio_direction_t         mDirection       = AAUDIO_DIRECTION_OUTPUT;
-    aaudio_usage_t             mUsage           = AAUDIO_UNSPECIFIED;
-    aaudio_content_type_t      mContentType     = AAUDIO_UNSPECIFIED;
-    aaudio_input_preset_t      mInputPreset     = AAUDIO_UNSPECIFIED;
-    int32_t                    mBufferCapacity  = AAUDIO_UNSPECIFIED;
-    aaudio_session_id_t        mSessionId       = AAUDIO_SESSION_ID_NONE;
+    int32_t                         mSamplesPerFrame      = AAUDIO_UNSPECIFIED;
+    int32_t                         mSampleRate           = AAUDIO_UNSPECIFIED;
+    int32_t                         mDeviceId             = AAUDIO_UNSPECIFIED;
+    aaudio_sharing_mode_t           mSharingMode          = AAUDIO_SHARING_MODE_SHARED;
+    audio_format_t                  mAudioFormat          = AUDIO_FORMAT_DEFAULT;
+    aaudio_direction_t              mDirection            = AAUDIO_DIRECTION_OUTPUT;
+    aaudio_usage_t                  mUsage                = AAUDIO_UNSPECIFIED;
+    aaudio_content_type_t           mContentType          = AAUDIO_UNSPECIFIED;
+    aaudio_input_preset_t           mInputPreset          = AAUDIO_UNSPECIFIED;
+    int32_t                         mBufferCapacity       = AAUDIO_UNSPECIFIED;
+    aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_UNSPECIFIED;
+    aaudio_session_id_t             mSessionId            = AAUDIO_SESSION_ID_NONE;
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index e39a075..732d45c 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -94,6 +94,10 @@
     if (mInputPreset == AAUDIO_UNSPECIFIED) {
         mInputPreset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
     }
+    mAllowedCapturePolicy = builder.getAllowedCapturePolicy();
+    if (mAllowedCapturePolicy == AAUDIO_UNSPECIFIED) {
+        mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
+    }
 
     // callbacks
     mFramesPerDataCallback = builder.getFramesPerDataCallback();
@@ -113,8 +117,8 @@
           mPerformanceMode,
           (isDataCallbackSet() ? "ON" : "OFF"),
           mFramesPerDataCallback);
-    ALOGI("open() usage  = %d, contentType = %d, inputPreset = %d",
-          mUsage, mContentType, mInputPreset);
+    ALOGI("open() usage  = %d, contentType = %d, inputPreset = %d, allowedCapturePolicy = %d",
+          mUsage, mContentType, mInputPreset, mAllowedCapturePolicy);
 
     return AAUDIO_OK;
 }
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 46951f5..32713b1 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -219,6 +219,10 @@
         return mInputPreset;
     }
 
+    aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
+        return mAllowedCapturePolicy;
+    }
+
     int32_t getSessionId() const {
         return mSessionId;
     }
@@ -525,6 +529,13 @@
         mInputPreset = inputPreset;
     }
 
+    /**
+     * This should not be called after the open() call.
+     */
+    void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
+        mAllowedCapturePolicy = policy;
+    }
+
 private:
 
     aaudio_result_t safeStop();
@@ -546,6 +557,7 @@
     aaudio_usage_t              mUsage           = AAUDIO_UNSPECIFIED;
     aaudio_content_type_t       mContentType     = AAUDIO_UNSPECIFIED;
     aaudio_input_preset_t       mInputPreset     = AAUDIO_UNSPECIFIED;
+    aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
 
     int32_t                     mSessionId = AAUDIO_UNSPECIFIED;
 
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index ff95aed..e359c1c 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -134,12 +134,14 @@
             AAudioConvert_contentTypeToInternal(builder.getContentType());
     const audio_usage_t usage =
             AAudioConvert_usageToInternal(builder.getUsage());
+    const audio_flags_mask_t attributesFlags =
+        AAudioConvert_allowCapturePolicyToAudioFlagsMask(builder.getAllowedCapturePolicy());
 
     const audio_attributes_t attributes = {
             .content_type = contentType,
             .usage = usage,
             .source = AUDIO_SOURCE_DEFAULT, // only used for recording
-            .flags = AUDIO_FLAG_NONE, // Different than the AUDIO_OUTPUT_FLAGS
+            .flags = attributesFlags,
             .tags = ""
     };
 
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 723cbf1..96ed56a 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -217,6 +217,22 @@
     return (audio_source_t) preset; // same value
 }
 
+audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+        aaudio_allowed_capture_policy_t policy) {
+    switch (policy) {
+        case AAUDIO_UNSPECIFIED:
+        case AAUDIO_ALLOW_CAPTURE_BY_ALL:
+            return AUDIO_FLAG_NONE;
+        case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
+            return AUDIO_FLAG_NO_MEDIA_PROJECTION;
+        case AAUDIO_ALLOW_CAPTURE_BY_NONE:
+            return AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE;
+        default:
+            ALOGE("%s() 0x%08X unrecognized", __func__, policy);
+            return AUDIO_FLAG_NONE; //
+    }
+}
+
 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
                                     int32_t bytesPerFrame,
                                     int32_t *sizeInBytes) {
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index dc2b198..76d0457 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -84,6 +84,14 @@
  */
 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset);
 
+/**
+ * Note that this function does not validate the passed in value.
+ * That is done somewhere else.
+ * @return internal audio flags mask
+ */
+audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
+        aaudio_allowed_capture_policy_t policy);
+
 // Note that this code may be replaced by Settings or by some other system configuration tool.
 
 #define AAUDIO_PROP_MMAP_POLICY           "aaudio.mmap_policy"