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