/* * Copyright 2018 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. */ #include #include #include #include #ifndef __ANDROID_API_S__ #define __ANDROID_API_S__ 31 #endif #ifndef __ANDROID_API_S_V2__ #define __ANDROID_API_S_V2__ 32 #endif using namespace oboe; class CallbackSizeMonitor : public AudioStreamCallback { public: DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override { framesPerCallback = numFrames; callbackCount++; return DataCallbackResult::Continue; } // This is exposed publicly so that the number of frames per callback can be tested. std::atomic framesPerCallback{0}; std::atomic callbackCount{0}; }; class StreamOpen : public ::testing::Test { protected: bool openStream() { EXPECT_EQ(mStream, nullptr); Result r = mBuilder.openStream(mStream); EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r); EXPECT_EQ(0, openCount) << "Should start with a fresh object every time."; openCount++; return (r == Result::OK); } bool closeStream() { if (mStream){ Result r = mStream->close(); EXPECT_EQ(r, Result::OK) << "Failed to close stream. " << convertToText(r); usleep(500 * 1000); // give previous stream time to settle return (r == Result::OK); } else { return true; } } void checkSampleRateConversionAdvancing(Direction direction) { CallbackSizeMonitor callback; mBuilder.setDirection(direction); if (mBuilder.isAAudioRecommended()) { mBuilder.setAudioApi(AudioApi::AAudio); } mBuilder.setCallback(&callback); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); mBuilder.setSampleRate(44100); mBuilder.setSampleRateConversionQuality(SampleRateConversionQuality::Medium); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->requestStart(), Result::OK); int timeout = 20; while (callback.framesPerCallback == 0 && timeout > 0) { usleep(50 * 1000); timeout--; } // Catch Issue #1166 mStream->getTimestamp(CLOCK_MONOTONIC); // should not crash mStream->getTimestamp(CLOCK_MONOTONIC, nullptr, nullptr); // should not crash ASSERT_GT(callback.callbackCount, 0); ASSERT_GT(callback.framesPerCallback, 0); ASSERT_EQ(mStream->requestStop(), Result::OK); ASSERT_TRUE(closeStream()); } AudioStreamBuilder mBuilder; std::shared_ptr mStream; int32_t openCount = 0; }; class StreamOpenOutput : public StreamOpen {}; class StreamOpenInput : public StreamOpen {}; TEST_F(StreamOpenOutput, ForOpenSLESDefaultSampleRateIsUsed){ DefaultStreamValues::SampleRate = 44100; DefaultStreamValues::FramesPerBurst = 192; mBuilder.setAudioApi(AudioApi::OpenSLES); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getSampleRate(), 44100); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, ForOpenSLESDefaultFramesPerBurstIsUsed){ DefaultStreamValues::SampleRate = 48000; DefaultStreamValues::FramesPerBurst = 128; // used for low latency mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); ASSERT_TRUE(openStream()); // Some devices like emulators may not support Low Latency if (mStream->getPerformanceMode() == PerformanceMode::LowLatency) { ASSERT_EQ(mStream->getFramesPerBurst(), 128); } ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, ForOpenSLESDefaultChannelCountIsUsed){ DefaultStreamValues::ChannelCount = 1; mBuilder.setAudioApi(AudioApi::OpenSLES); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getChannelCount(), 1); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OutputForOpenSLESPerformanceModeShouldBeNone){ // We will not get a LowLatency stream if we request 16000 Hz. mBuilder.setSampleRate(16000); mBuilder.setSampleRateConversionQuality(SampleRateConversionQuality::None); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::OpenSLES); ASSERT_TRUE(openStream()); ASSERT_EQ((int)mStream->getPerformanceMode(), (int)PerformanceMode::None); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenInput, InputForOpenSLESPerformanceModeShouldBeNone){ // We will not get a LowLatency stream if we request 16000 Hz. mBuilder.setSampleRate(16000); mBuilder.setSampleRateConversionQuality(SampleRateConversionQuality::None); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::OpenSLES); ASSERT_TRUE(openStream()); ASSERT_EQ((int)mStream->getPerformanceMode(), (int)PerformanceMode::None); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, ForOpenSlesIllegalFormatRejectedOutput) { mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); mBuilder.setFormat(static_cast(666)); Result r = mBuilder.openStream(mStream); EXPECT_NE(r, Result::OK) << "Should not open stream " << convertToText(r); if (mStream != nullptr) { mStream->close(); // just in case it accidentally opened } } TEST_F(StreamOpenInput, ForOpenSlesIllegalFormatRejectedInput) { mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); mBuilder.setDirection(Direction::Input); mBuilder.setFormat(static_cast(666)); Result r = mBuilder.openStream(mStream); EXPECT_NE(r, Result::OK) << "Should not open stream " << convertToText(r); if (mStream != nullptr) { mStream->close(); // just in case it accidentally opened } } // Make sure the callback is called with the requested FramesPerCallback TEST_F(StreamOpenOutput, OpenSLESFramesPerCallback) { const int kRequestedFramesPerCallback = 417; CallbackSizeMonitor callback; DefaultStreamValues::SampleRate = 48000; DefaultStreamValues::ChannelCount = 2; DefaultStreamValues::FramesPerBurst = 192; mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setFramesPerCallback(kRequestedFramesPerCallback); mBuilder.setCallback(&callback); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->requestStart(), Result::OK); int timeout = 20; while (callback.framesPerCallback == 0 && timeout > 0) { usleep(50 * 1000); timeout--; } ASSERT_EQ(kRequestedFramesPerCallback, callback.framesPerCallback); ASSERT_EQ(kRequestedFramesPerCallback, mStream->getFramesPerCallback()); ASSERT_EQ(mStream->requestStop(), Result::OK); ASSERT_TRUE(closeStream()); } // Make sure the LowLatency callback has the requested FramesPerCallback. TEST_F(StreamOpen, AAudioFramesPerCallbackLowLatency) { const int kRequestedFramesPerCallback = 192; CallbackSizeMonitor callback; mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setFramesPerCallback(kRequestedFramesPerCallback); mBuilder.setCallback(&callback); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); ASSERT_TRUE(openStream()); ASSERT_EQ(kRequestedFramesPerCallback, mStream->getFramesPerCallback()); ASSERT_EQ(mStream->requestStart(), Result::OK); int timeout = 20; while (callback.framesPerCallback == 0 && timeout > 0) { usleep(50 * 1000); timeout--; } ASSERT_EQ(kRequestedFramesPerCallback, callback.framesPerCallback); ASSERT_EQ(mStream->requestStop(), Result::OK); ASSERT_TRUE(closeStream()); } // Make sure the regular callback has the requested FramesPerCallback. TEST_F(StreamOpen, AAudioFramesPerCallbackNone) { const int kRequestedFramesPerCallback = 1024; CallbackSizeMonitor callback; mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setFramesPerCallback(kRequestedFramesPerCallback); mBuilder.setCallback(&callback); mBuilder.setPerformanceMode(PerformanceMode::None); ASSERT_TRUE(openStream()); ASSERT_EQ(kRequestedFramesPerCallback, mStream->getFramesPerCallback()); ASSERT_EQ(mStream->requestStart(), Result::OK); int timeout = 20; while (callback.framesPerCallback == 0 && timeout > 0) { usleep(50 * 1000); timeout--; } ASSERT_EQ(kRequestedFramesPerCallback, callback.framesPerCallback); ASSERT_EQ(mStream->requestStop(), Result::OK); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenInput, RecordingFormatUnspecifiedReturnsI16BeforeMarshmallow){ if (getSdkVersion() < __ANDROID_API_M__){ mBuilder.setDirection(Direction::Input); mBuilder.setFormat(AudioFormat::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::I16); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, RecordingFormatUnspecifiedReturnsFloatOnMarshmallowAndLater){ if (getSdkVersion() >= __ANDROID_API_M__){ mBuilder.setDirection(Direction::Input); mBuilder.setFormat(AudioFormat::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::Float); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, RecordingFormatFloatReturnsErrorBeforeMarshmallow){ if (getSdkVersion() < __ANDROID_API_M__){ mBuilder.setDirection(Direction::Input); mBuilder.setFormat(AudioFormat::Float); Result r = mBuilder.openStream(mStream); ASSERT_EQ(r, Result::ErrorInvalidFormat) << convertToText(r); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, RecordingFormatFloatReturnsFloatOnMarshmallowAndLater){ if (getSdkVersion() >= __ANDROID_API_M__){ mBuilder.setDirection(Direction::Input); mBuilder.setFormat(AudioFormat::Float); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::Float); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, RecordingFormatI16ReturnsI16){ mBuilder.setDirection(Direction::Input); mBuilder.setFormat(AudioFormat::I16); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::I16); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, PlaybackFormatUnspecifiedReturnsI16BeforeLollipop){ if (getSdkVersion() < __ANDROID_API_L__){ mBuilder.setDirection(Direction::Output); mBuilder.setFormat(AudioFormat::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::I16); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, PlaybackFormatUnspecifiedReturnsFloatOnLollipopAndLater){ if (getSdkVersion() >= __ANDROID_API_L__){ mBuilder.setDirection(Direction::Output); mBuilder.setFormat(AudioFormat::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::Float); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, PlaybackFormatFloatReturnsErrorBeforeLollipop){ if (getSdkVersion() < __ANDROID_API_L__){ mBuilder.setDirection(Direction::Output); mBuilder.setFormat(AudioFormat::Float); Result r = mBuilder.openStream(mStream); ASSERT_EQ(r, Result::ErrorInvalidFormat); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, PlaybackFormatFloatReturnsFloatWithFormatConversionAllowed){ mBuilder.setDirection(Direction::Output); mBuilder.setFormat(AudioFormat::Float); mBuilder.setFormatConversionAllowed(true); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::Float); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, PlaybackFormatFloatReturnsFloatOnLollipopAndLater){ if (getSdkVersion() >= __ANDROID_API_L__){ mBuilder.setDirection(Direction::Output); mBuilder.setFormat(AudioFormat::Float); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::Float); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, PlaybackFormatI16ReturnsI16) { mBuilder.setDirection(Direction::Output); mBuilder.setFormat(AudioFormat::I16); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getFormat(), AudioFormat::I16); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OpenCloseLowLatencyStream){ mBuilder.setDirection(Direction::Output); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); float *buf = new float[100]; ASSERT_TRUE(openStream()); delete[] buf; ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, LowLatencyStreamHasSmallBufferSize){ if (mBuilder.isAAudioRecommended()) { mBuilder.setDirection(Direction::Output); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); ASSERT_TRUE(openStream()); int32_t bufferSize = mStream->getBufferSizeInFrames(); int32_t burst = mStream->getFramesPerBurst(); ASSERT_TRUE(closeStream()); ASSERT_LE(bufferSize, burst * 3); } } // Make sure the parameters get copied from the child stream. TEST_F(StreamOpenOutput, AAudioOutputSampleRate44100FilterConfiguration) { if (mBuilder.isAAudioRecommended()) { mBuilder.setDirection(Direction::Output); mBuilder.setPerformanceMode(PerformanceMode::LowLatency); mBuilder.setSharingMode(SharingMode::Exclusive); // Try to force the use of a FilterAudioStream by requesting conversion. mBuilder.setSampleRate(44100); mBuilder.setSampleRateConversionQuality(SampleRateConversionQuality::Medium); ASSERT_TRUE(openStream()); if (getSdkVersion() >= __ANDROID_API_U__) { ASSERT_LT(0, mStream->getHardwareSampleRate()); ASSERT_LT(0, mStream->getHardwareChannelCount()); ASSERT_LT(0, (int)mStream->getHardwareFormat()); } // If MMAP is not supported then we cannot get an EXCLUSIVE mode stream. if (!AAudioExtensions::getInstance().isMMapSupported()) { ASSERT_NE(SharingMode::Exclusive, mStream->getSharingMode()); // IMPOSSIBLE } ASSERT_TRUE(closeStream()); } } // See if sample rate conversion by Oboe is calling the callback. TEST_F(StreamOpenOutput, AAudioOutputSampleRate44100) { checkSampleRateConversionAdvancing(Direction::Output); } // See if sample rate conversion by Oboe is calling the callback. TEST_F(StreamOpenInput, AAudioInputSampleRate44100) { checkSampleRateConversionAdvancing(Direction::Input); } TEST_F(StreamOpenOutput, AAudioOutputSetPackageName){ if (getSdkVersion() >= __ANDROID_API_S__){ mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setPackageName("com.google.oboe.tests.unittestrunner"); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->requestStart(), Result::OK); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetPackageName){ if (getSdkVersion() >= __ANDROID_API_S__){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setPackageName("com.google.oboe.tests.unittestrunner"); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->requestStart(), Result::OK); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputSetAttributionTag){ if (getSdkVersion() >= __ANDROID_API_S__){ mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAttributionTag("TestSetOutputAttributionTag"); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->requestStart(), Result::OK); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetAttributionTag){ if (getSdkVersion() >= __ANDROID_API_S__){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAttributionTag("TestSetInputAttributionTag"); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->requestStart(), Result::OK); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetSpatializationBehavior) { mBuilder.setDirection(Direction::Input); mBuilder.setSpatializationBehavior(SpatializationBehavior::Auto); ASSERT_TRUE(openStream()); if (getSdkVersion() >= __ANDROID_API_S_V2__){ ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Auto); } else { ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never); } ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, AAudioOutputSetSpatializationBehavior) { mBuilder.setDirection(Direction::Output); mBuilder.setSpatializationBehavior(SpatializationBehavior::Never); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OpenSLESOutputSetSpatializationBehavior) { mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setSpatializationBehavior(SpatializationBehavior::Auto); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenInput, AAudioInputSetSpatializationBehaviorUnspecified) { mBuilder.setDirection(Direction::Input); mBuilder.setSpatializationBehavior(SpatializationBehavior::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, AAudioOutputSetSpatializationBehaviorUnspecified) { mBuilder.setDirection(Direction::Output); mBuilder.setSpatializationBehavior(SpatializationBehavior::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenInput, AAudioInputSetIsContentSpatialized) { mBuilder.setDirection(Direction::Input); mBuilder.setIsContentSpatialized(true); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->isContentSpatialized(), true); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, AAudioOutputSetIsContentSpatialized) { mBuilder.setDirection(Direction::Output); mBuilder.setIsContentSpatialized(true); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->isContentSpatialized(), true); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OpenSLESOutputSetIsContentSpatialized) { mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setIsContentSpatialized(true); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->isContentSpatialized(), true); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, AAudioOutputSetIsContentSpatializedFalse) { mBuilder.setDirection(Direction::Output); mBuilder.setIsContentSpatialized(false); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->isContentSpatialized(), false); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, AAudioOutputSetIsContentSpatializedUnspecified) { mBuilder.setDirection(Direction::Output); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->isContentSpatialized(), false); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenInput, AAudioInputSetIsContentSpatializedUnspecified) { mBuilder.setDirection(Direction::Input); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->isContentSpatialized(), false); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OutputForOpenSLESPerformanceModeNoneGetBufferSizeInFrames){ mBuilder.setPerformanceMode(PerformanceMode::None); mBuilder.setAudioApi(AudioApi::OpenSLES); ASSERT_TRUE(openStream()); EXPECT_GT(mStream->getBufferSizeInFrames(), 0); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OboeExtensions){ if (OboeExtensions::isMMapSupported()) { ASSERT_EQ(OboeExtensions::setMMapEnabled(true), 0); ASSERT_TRUE(OboeExtensions::isMMapEnabled()); ASSERT_EQ(OboeExtensions::setMMapEnabled(false), 0); ASSERT_FALSE(OboeExtensions::isMMapEnabled()); ASSERT_TRUE(openStream()); EXPECT_FALSE(OboeExtensions::isMMapUsed(mStream.get())); ASSERT_TRUE(closeStream()); ASSERT_EQ(OboeExtensions::setMMapEnabled(true), 0); ASSERT_TRUE(OboeExtensions::isMMapEnabled()); } } TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeUnspecifiedUnprocessed){ if (getSdkVersion() >= __ANDROID_API_R__){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setInputPreset(InputPreset::Unprocessed); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Disabled); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeUnspecifiedVoiceCommunication){ if (getSdkVersion() >= __ANDROID_API_R__){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setInputPreset(InputPreset::VoiceCommunication); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Enabled); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeVoiceDisabled){ if (getSdkVersion() >= __ANDROID_API_R__){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setInputPreset(InputPreset::VoiceCommunication); mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Disabled); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Disabled); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeUnprocessedEnabled){ if (getSdkVersion() >= __ANDROID_API_R__){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setInputPreset(InputPreset::Unprocessed); mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Enabled); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputSetPrivacySensitiveModeGetsUnspecified){ if (getSdkVersion() >= __ANDROID_API_R__){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Unspecified); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, OpenSLESInputSetPrivacySensitiveModeDoesNotCrash){ mBuilder.setDirection(Direction::Input); mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setInputPreset(InputPreset::Unprocessed); mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Unspecified); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenInput, OldAndroidVersionInputSetPrivacySensitiveModeDoesNotCrash){ if (getSdkVersion() < __ANDROID_API_R__) { mBuilder.setDirection(Direction::Input); mBuilder.setInputPreset(InputPreset::Unprocessed); mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Unspecified); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicyUnspecifiedGetsAll){ if (getSdkVersion() >= __ANDROID_API_Q__){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::Unspecified); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::All); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicyAll){ if (getSdkVersion() >= __ANDROID_API_Q__){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::All); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicySystem){ if (getSdkVersion() >= __ANDROID_API_Q__){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::System); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::System); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicyNone){ if (getSdkVersion() >= __ANDROID_API_Q__){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::None); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::None); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenOutput, AAudioOutputDoNotSetAllowedCapturePolicy){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); ASSERT_TRUE(openStream()); if (getSdkVersion() >= __ANDROID_API_Q__){ ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::All); } else { ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified); } ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, OpenSLESOutputSetAllowedCapturePolicyAllGetsUnspecified){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::OpenSLES); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified); ASSERT_TRUE(closeStream()); } TEST_F(StreamOpenOutput, AAudioBeforeQOutputSetAllowedCapturePolicyAllGetsUnspecified){ if (getSdkVersion() < __ANDROID_API_Q__){ mBuilder.setDirection(Direction::Output); mBuilder.setAudioApi(AudioApi::AAudio); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified); ASSERT_TRUE(closeStream()); } } TEST_F(StreamOpenInput, AAudioInputSetAllowedCapturePolicyAllGetsUnspecified){ mBuilder.setDirection(Direction::Input); mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All); ASSERT_TRUE(openStream()); ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified); ASSERT_TRUE(closeStream()); }