1*b7c941bbSAndroid Build Coastguard Worker /* 2*b7c941bbSAndroid Build Coastguard Worker * Copyright 2017 The Android Open Source Project 3*b7c941bbSAndroid Build Coastguard Worker * 4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*b7c941bbSAndroid Build Coastguard Worker * 8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*b7c941bbSAndroid Build Coastguard Worker * 10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License. 15*b7c941bbSAndroid Build Coastguard Worker */ 16*b7c941bbSAndroid Build Coastguard Worker #ifndef CTS_MEDIA_TEST_AAUDIO_UTILS_H 17*b7c941bbSAndroid Build Coastguard Worker #define CTS_MEDIA_TEST_AAUDIO_UTILS_H 18*b7c941bbSAndroid Build Coastguard Worker 19*b7c941bbSAndroid Build Coastguard Worker #include <dlfcn.h> 20*b7c941bbSAndroid Build Coastguard Worker #include <atomic> 21*b7c941bbSAndroid Build Coastguard Worker #include <map> 22*b7c941bbSAndroid Build Coastguard Worker #include <unordered_set> 23*b7c941bbSAndroid Build Coastguard Worker #include <gtest/gtest.h> 24*b7c941bbSAndroid Build Coastguard Worker #include <sys/system_properties.h> 25*b7c941bbSAndroid Build Coastguard Worker 26*b7c941bbSAndroid Build Coastguard Worker #include <android/binder_auto_utils.h> 27*b7c941bbSAndroid Build Coastguard Worker #include <android/binder_ibinder.h> 28*b7c941bbSAndroid Build Coastguard Worker 29*b7c941bbSAndroid Build Coastguard Worker #include <aaudio/AAudio.h> 30*b7c941bbSAndroid Build Coastguard Worker #include <system/audio.h> /* FCC_LIMIT */ 31*b7c941bbSAndroid Build Coastguard Worker 32*b7c941bbSAndroid Build Coastguard Worker #include "test_aaudio.h" // NANOS_PER_MILLISECOND 33*b7c941bbSAndroid Build Coastguard Worker 34*b7c941bbSAndroid Build Coastguard Worker int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC); 35*b7c941bbSAndroid Build Coastguard Worker const char* performanceModeToString(aaudio_performance_mode_t mode); 36*b7c941bbSAndroid Build Coastguard Worker const char* sharingModeToString(aaudio_sharing_mode_t mode); 37*b7c941bbSAndroid Build Coastguard Worker 38*b7c941bbSAndroid Build Coastguard Worker static constexpr const char* FEATURE_PLAYBACK = "android.hardware.audio.output"; 39*b7c941bbSAndroid Build Coastguard Worker static constexpr const char* FEATURE_RECORDING = "android.hardware.microphone"; 40*b7c941bbSAndroid Build Coastguard Worker static constexpr const char* FEATURE_LOW_LATENCY = "android.hardware.audio.low_latency"; 41*b7c941bbSAndroid Build Coastguard Worker bool deviceSupportsFeature(const char* feature); 42*b7c941bbSAndroid Build Coastguard Worker 43*b7c941bbSAndroid Build Coastguard Worker class StreamBuilderHelper { 44*b7c941bbSAndroid Build Coastguard Worker public: 45*b7c941bbSAndroid Build Coastguard Worker struct Parameters { 46*b7c941bbSAndroid Build Coastguard Worker int32_t sampleRate; 47*b7c941bbSAndroid Build Coastguard Worker int32_t channelCount; 48*b7c941bbSAndroid Build Coastguard Worker aaudio_format_t dataFormat; 49*b7c941bbSAndroid Build Coastguard Worker aaudio_sharing_mode_t sharingMode; 50*b7c941bbSAndroid Build Coastguard Worker aaudio_performance_mode_t perfMode; 51*b7c941bbSAndroid Build Coastguard Worker }; 52*b7c941bbSAndroid Build Coastguard Worker 53*b7c941bbSAndroid Build Coastguard Worker void initBuilder(); 54*b7c941bbSAndroid Build Coastguard Worker void createAndVerifyStream(bool *success); 55*b7c941bbSAndroid Build Coastguard Worker void close(); 56*b7c941bbSAndroid Build Coastguard Worker startStream()57*b7c941bbSAndroid Build Coastguard Worker void startStream() { 58*b7c941bbSAndroid Build Coastguard Worker streamCommand(&AAudioStream_requestStart, 59*b7c941bbSAndroid Build Coastguard Worker AAUDIO_STREAM_STATE_STARTING, AAUDIO_STREAM_STATE_STARTED); 60*b7c941bbSAndroid Build Coastguard Worker } pauseStream()61*b7c941bbSAndroid Build Coastguard Worker void pauseStream() { 62*b7c941bbSAndroid Build Coastguard Worker streamCommand(&AAudioStream_requestPause, 63*b7c941bbSAndroid Build Coastguard Worker AAUDIO_STREAM_STATE_PAUSING, AAUDIO_STREAM_STATE_PAUSED); 64*b7c941bbSAndroid Build Coastguard Worker } stopStream()65*b7c941bbSAndroid Build Coastguard Worker void stopStream() { 66*b7c941bbSAndroid Build Coastguard Worker streamCommand(&AAudioStream_requestStop, 67*b7c941bbSAndroid Build Coastguard Worker AAUDIO_STREAM_STATE_STOPPING, AAUDIO_STREAM_STATE_STOPPED); 68*b7c941bbSAndroid Build Coastguard Worker } 69*b7c941bbSAndroid Build Coastguard Worker waitForState(aaudio_stream_state_t targetState)70*b7c941bbSAndroid Build Coastguard Worker void waitForState(aaudio_stream_state_t targetState) { 71*b7c941bbSAndroid Build Coastguard Worker aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN; 72*b7c941bbSAndroid Build Coastguard Worker const int kNumTries = 4; // max number of states we expect to transition through 73*b7c941bbSAndroid Build Coastguard Worker for (int i = 0; ((i < kNumTries) && (state != targetState)); i++) { 74*b7c941bbSAndroid Build Coastguard Worker EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream(), 75*b7c941bbSAndroid Build Coastguard Worker state, 76*b7c941bbSAndroid Build Coastguard Worker &state, 77*b7c941bbSAndroid Build Coastguard Worker DEFAULT_STATE_TIMEOUT)); 78*b7c941bbSAndroid Build Coastguard Worker } 79*b7c941bbSAndroid Build Coastguard Worker } 80*b7c941bbSAndroid Build Coastguard Worker flushStream()81*b7c941bbSAndroid Build Coastguard Worker void flushStream() { 82*b7c941bbSAndroid Build Coastguard Worker streamCommand(&AAudioStream_requestFlush, 83*b7c941bbSAndroid Build Coastguard Worker AAUDIO_STREAM_STATE_FLUSHING, AAUDIO_STREAM_STATE_FLUSHED); 84*b7c941bbSAndroid Build Coastguard Worker } 85*b7c941bbSAndroid Build Coastguard Worker builder()86*b7c941bbSAndroid Build Coastguard Worker AAudioStreamBuilder* builder() const { return mBuilder; } stream()87*b7c941bbSAndroid Build Coastguard Worker AAudioStream* stream() const { return mStream; } actual()88*b7c941bbSAndroid Build Coastguard Worker const Parameters& actual() const { return mActual; } framesPerBurst()89*b7c941bbSAndroid Build Coastguard Worker int32_t framesPerBurst() const { return mFramesPerBurst; } 90*b7c941bbSAndroid Build Coastguard Worker 91*b7c941bbSAndroid Build Coastguard Worker protected: 92*b7c941bbSAndroid Build Coastguard Worker StreamBuilderHelper(aaudio_direction_t direction, int32_t sampleRate, 93*b7c941bbSAndroid Build Coastguard Worker int32_t channelCount, aaudio_format_t dataFormat, 94*b7c941bbSAndroid Build Coastguard Worker aaudio_sharing_mode_t sharingMode, aaudio_performance_mode_t perfMode); 95*b7c941bbSAndroid Build Coastguard Worker ~StreamBuilderHelper(); 96*b7c941bbSAndroid Build Coastguard Worker 97*b7c941bbSAndroid Build Coastguard Worker typedef aaudio_result_t (StreamCommand)(AAudioStream*); 98*b7c941bbSAndroid Build Coastguard Worker void streamCommand( 99*b7c941bbSAndroid Build Coastguard Worker StreamCommand cmd, aaudio_stream_state_t fromState, aaudio_stream_state_t toState); 100*b7c941bbSAndroid Build Coastguard Worker 101*b7c941bbSAndroid Build Coastguard Worker static const std::map<aaudio_performance_mode_t, int64_t> sMaxFramesPerBurstMs; 102*b7c941bbSAndroid Build Coastguard Worker static const std::unordered_set<aaudio_format_t> sValidStreamFormats; 103*b7c941bbSAndroid Build Coastguard Worker const aaudio_direction_t mDirection; 104*b7c941bbSAndroid Build Coastguard Worker const Parameters mRequested; 105*b7c941bbSAndroid Build Coastguard Worker Parameters mActual; 106*b7c941bbSAndroid Build Coastguard Worker int32_t mFramesPerBurst; 107*b7c941bbSAndroid Build Coastguard Worker AAudioStreamBuilder *mBuilder; 108*b7c941bbSAndroid Build Coastguard Worker AAudioStream *mStream; 109*b7c941bbSAndroid Build Coastguard Worker 110*b7c941bbSAndroid Build Coastguard Worker private: 111*b7c941bbSAndroid Build Coastguard Worker const int32_t kMinValidSampleRate = 8000; // 8 kHz 112*b7c941bbSAndroid Build Coastguard Worker const int32_t kMaxValidSampleRate = 2000000; // 2 MHz 113*b7c941bbSAndroid Build Coastguard Worker const int32_t kMinValidChannelCount = 1; 114*b7c941bbSAndroid Build Coastguard Worker const int32_t kMaxValidChannelCount = FCC_LIMIT; 115*b7c941bbSAndroid Build Coastguard Worker }; 116*b7c941bbSAndroid Build Coastguard Worker 117*b7c941bbSAndroid Build Coastguard Worker class InputStreamBuilderHelper : public StreamBuilderHelper { 118*b7c941bbSAndroid Build Coastguard Worker public: 119*b7c941bbSAndroid Build Coastguard Worker InputStreamBuilderHelper( 120*b7c941bbSAndroid Build Coastguard Worker aaudio_sharing_mode_t requestedSharingMode, 121*b7c941bbSAndroid Build Coastguard Worker aaudio_performance_mode_t requestedPerfMode, 122*b7c941bbSAndroid Build Coastguard Worker aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_FLOAT, 123*b7c941bbSAndroid Build Coastguard Worker int32_t requestedSampleRate = 48000); 124*b7c941bbSAndroid Build Coastguard Worker }; 125*b7c941bbSAndroid Build Coastguard Worker 126*b7c941bbSAndroid Build Coastguard Worker class OutputStreamBuilderHelper : public StreamBuilderHelper { 127*b7c941bbSAndroid Build Coastguard Worker public: 128*b7c941bbSAndroid Build Coastguard Worker OutputStreamBuilderHelper( 129*b7c941bbSAndroid Build Coastguard Worker aaudio_sharing_mode_t requestedSharingMode, 130*b7c941bbSAndroid Build Coastguard Worker aaudio_performance_mode_t requestedPerfMode, 131*b7c941bbSAndroid Build Coastguard Worker aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_I16, 132*b7c941bbSAndroid Build Coastguard Worker int32_t requestSampleRate = 48000); 133*b7c941bbSAndroid Build Coastguard Worker void initBuilder(); 134*b7c941bbSAndroid Build Coastguard Worker 135*b7c941bbSAndroid Build Coastguard Worker private: 136*b7c941bbSAndroid Build Coastguard Worker const int32_t kBufferCapacityFrames = 2000; 137*b7c941bbSAndroid Build Coastguard Worker }; 138*b7c941bbSAndroid Build Coastguard Worker 139*b7c941bbSAndroid Build Coastguard Worker class AAudioExtensions { 140*b7c941bbSAndroid Build Coastguard Worker public: 141*b7c941bbSAndroid Build Coastguard Worker AAudioExtensions(); 142*b7c941bbSAndroid Build Coastguard Worker isPolicyEnabled(int32_t policy)143*b7c941bbSAndroid Build Coastguard Worker static bool isPolicyEnabled(int32_t policy) { 144*b7c941bbSAndroid Build Coastguard Worker return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS); 145*b7c941bbSAndroid Build Coastguard Worker } 146*b7c941bbSAndroid Build Coastguard Worker getInstance()147*b7c941bbSAndroid Build Coastguard Worker static AAudioExtensions &getInstance() { 148*b7c941bbSAndroid Build Coastguard Worker static AAudioExtensions instance; 149*b7c941bbSAndroid Build Coastguard Worker return instance; 150*b7c941bbSAndroid Build Coastguard Worker } 151*b7c941bbSAndroid Build Coastguard Worker getMMapPolicyProperty()152*b7c941bbSAndroid Build Coastguard Worker static int getMMapPolicyProperty() { 153*b7c941bbSAndroid Build Coastguard Worker return getIntegerProperty("aaudio.mmap_policy", AAUDIO_UNSPECIFIED); 154*b7c941bbSAndroid Build Coastguard Worker } 155*b7c941bbSAndroid Build Coastguard Worker getMMapPolicy()156*b7c941bbSAndroid Build Coastguard Worker aaudio_policy_t getMMapPolicy() { return AAudio_getMMapPolicy(); } 157*b7c941bbSAndroid Build Coastguard Worker setMMapPolicy(aaudio_policy_t policy)158*b7c941bbSAndroid Build Coastguard Worker int32_t setMMapPolicy(aaudio_policy_t policy) { return AAudio_setMMapPolicy(policy); } 159*b7c941bbSAndroid Build Coastguard Worker isMMapUsed(AAudioStream * aaudioStream)160*b7c941bbSAndroid Build Coastguard Worker bool isMMapUsed(AAudioStream* aaudioStream) { return AAudioStream_isMMapUsed(aaudioStream); } 161*b7c941bbSAndroid Build Coastguard Worker setMMapEnabled(bool enabled)162*b7c941bbSAndroid Build Coastguard Worker int32_t setMMapEnabled(bool enabled) { 163*b7c941bbSAndroid Build Coastguard Worker return setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER); 164*b7c941bbSAndroid Build Coastguard Worker } 165*b7c941bbSAndroid Build Coastguard Worker isMMapEnabled()166*b7c941bbSAndroid Build Coastguard Worker bool isMMapEnabled() { return isPolicyEnabled(AAudio_getMMapPolicy()); } 167*b7c941bbSAndroid Build Coastguard Worker isMMapSupported()168*b7c941bbSAndroid Build Coastguard Worker bool isMMapSupported() const { 169*b7c941bbSAndroid Build Coastguard Worker return mMMapSupported; 170*b7c941bbSAndroid Build Coastguard Worker } 171*b7c941bbSAndroid Build Coastguard Worker isMMapExclusiveSupported()172*b7c941bbSAndroid Build Coastguard Worker bool isMMapExclusiveSupported() const { 173*b7c941bbSAndroid Build Coastguard Worker return mMMapExclusiveSupported; 174*b7c941bbSAndroid Build Coastguard Worker } 175*b7c941bbSAndroid Build Coastguard Worker getPlatformMMapPolicy(AAudio_DeviceType device,aaudio_direction_t direction)176*b7c941bbSAndroid Build Coastguard Worker aaudio_policy_t getPlatformMMapPolicy(AAudio_DeviceType device, 177*b7c941bbSAndroid Build Coastguard Worker aaudio_direction_t direction) const { 178*b7c941bbSAndroid Build Coastguard Worker return AAudio_getPlatformMMapPolicy(device, direction); 179*b7c941bbSAndroid Build Coastguard Worker } 180*b7c941bbSAndroid Build Coastguard Worker getPlatformMMapExclusivePolicy(AAudio_DeviceType device,aaudio_direction_t direction)181*b7c941bbSAndroid Build Coastguard Worker aaudio_policy_t getPlatformMMapExclusivePolicy(AAudio_DeviceType device, 182*b7c941bbSAndroid Build Coastguard Worker aaudio_direction_t direction) const { 183*b7c941bbSAndroid Build Coastguard Worker return AAudio_getPlatformMMapExclusivePolicy(device, direction); 184*b7c941bbSAndroid Build Coastguard Worker } 185*b7c941bbSAndroid Build Coastguard Worker 186*b7c941bbSAndroid Build Coastguard Worker private: 187*b7c941bbSAndroid Build Coastguard Worker 188*b7c941bbSAndroid Build Coastguard Worker static int getIntegerProperty(const char *name, int defaultValue); 189*b7c941bbSAndroid Build Coastguard Worker 190*b7c941bbSAndroid Build Coastguard Worker const bool mMMapSupported; 191*b7c941bbSAndroid Build Coastguard Worker const bool mMMapExclusiveSupported; 192*b7c941bbSAndroid Build Coastguard Worker }; 193*b7c941bbSAndroid Build Coastguard Worker 194*b7c941bbSAndroid Build Coastguard Worker class AudioServerCrashMonitor { 195*b7c941bbSAndroid Build Coastguard Worker public: getInstance()196*b7c941bbSAndroid Build Coastguard Worker static AudioServerCrashMonitor& getInstance() { 197*b7c941bbSAndroid Build Coastguard Worker static AudioServerCrashMonitor instance; 198*b7c941bbSAndroid Build Coastguard Worker return instance; 199*b7c941bbSAndroid Build Coastguard Worker } 200*b7c941bbSAndroid Build Coastguard Worker ~AudioServerCrashMonitor(); 201*b7c941bbSAndroid Build Coastguard Worker 202*b7c941bbSAndroid Build Coastguard Worker void linkToDeath(); 203*b7c941bbSAndroid Build Coastguard Worker isDeathRecipientLinked()204*b7c941bbSAndroid Build Coastguard Worker bool isDeathRecipientLinked() const { return mDeathRecipientLinked; } 205*b7c941bbSAndroid Build Coastguard Worker void onAudioServerCrash(); 206*b7c941bbSAndroid Build Coastguard Worker 207*b7c941bbSAndroid Build Coastguard Worker private: 208*b7c941bbSAndroid Build Coastguard Worker AudioServerCrashMonitor(); 209*b7c941bbSAndroid Build Coastguard Worker 210*b7c941bbSAndroid Build Coastguard Worker ::ndk::SpAIBinder getAudioFlinger(); 211*b7c941bbSAndroid Build Coastguard Worker 212*b7c941bbSAndroid Build Coastguard Worker ::ndk::SpAIBinder mAudioFlinger; 213*b7c941bbSAndroid Build Coastguard Worker ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 214*b7c941bbSAndroid Build Coastguard Worker bool mDeathRecipientLinked = false; 215*b7c941bbSAndroid Build Coastguard Worker }; 216*b7c941bbSAndroid Build Coastguard Worker 217*b7c941bbSAndroid Build Coastguard Worker class AAudioCtsBase : public ::testing::Test { 218*b7c941bbSAndroid Build Coastguard Worker protected: 219*b7c941bbSAndroid Build Coastguard Worker void SetUp() override; 220*b7c941bbSAndroid Build Coastguard Worker void TearDown() override; 221*b7c941bbSAndroid Build Coastguard Worker 222*b7c941bbSAndroid Build Coastguard Worker private: 223*b7c941bbSAndroid Build Coastguard Worker void checkIfAudioServerCrash(); 224*b7c941bbSAndroid Build Coastguard Worker }; 225*b7c941bbSAndroid Build Coastguard Worker 226*b7c941bbSAndroid Build Coastguard Worker bool isIEC61937Supported(); 227*b7c941bbSAndroid Build Coastguard Worker 228*b7c941bbSAndroid Build Coastguard Worker bool isEchoReferenceSupported(); 229*b7c941bbSAndroid Build Coastguard Worker 230*b7c941bbSAndroid Build Coastguard Worker void enableAudioOutputPermission(); 231*b7c941bbSAndroid Build Coastguard Worker 232*b7c941bbSAndroid Build Coastguard Worker void enableAudioHotwordPermission(); 233*b7c941bbSAndroid Build Coastguard Worker 234*b7c941bbSAndroid Build Coastguard Worker void disablePermissions(); 235*b7c941bbSAndroid Build Coastguard Worker 236*b7c941bbSAndroid Build Coastguard Worker bool isCompressedFormat(aaudio_format_t format); 237*b7c941bbSAndroid Build Coastguard Worker 238*b7c941bbSAndroid Build Coastguard Worker #endif // CTS_MEDIA_TEST_AAUDIO_UTILS_H 239