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 <map> 21 #include <sys/system_properties.h> 22 23 #include <aaudio/AAudio.h> 24 25 #include "test_aaudio.h" // NANOS_PER_MILLISECOND 26 27 int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC); 28 const char* performanceModeToString(aaudio_performance_mode_t mode); 29 const char* sharingModeToString(aaudio_sharing_mode_t mode); 30 31 static constexpr const char* FEATURE_PLAYBACK = "android.hardware.audio.output"; 32 static constexpr const char* FEATURE_RECORDING = "android.hardware.microphone"; 33 static constexpr const char* FEATURE_LOW_LATENCY = "android.hardware.audio.low_latency"; 34 bool deviceSupportsFeature(const char* feature); 35 36 class StreamBuilderHelper { 37 public: 38 struct Parameters { 39 int32_t sampleRate; 40 int32_t channelCount; 41 aaudio_format_t dataFormat; 42 aaudio_sharing_mode_t sharingMode; 43 aaudio_performance_mode_t perfMode; 44 }; 45 46 void initBuilder(); 47 void createAndVerifyStream(bool *success); 48 void close(); 49 startStream()50 void startStream() { 51 streamCommand(&AAudioStream_requestStart, 52 AAUDIO_STREAM_STATE_STARTING, AAUDIO_STREAM_STATE_STARTED); 53 } pauseStream()54 void pauseStream() { 55 streamCommand(&AAudioStream_requestPause, 56 AAUDIO_STREAM_STATE_PAUSING, AAUDIO_STREAM_STATE_PAUSED); 57 } stopStream()58 void stopStream() { 59 streamCommand(&AAudioStream_requestStop, 60 AAUDIO_STREAM_STATE_STOPPING, AAUDIO_STREAM_STATE_STOPPED); 61 } 62 waitForState(aaudio_stream_state_t targetState)63 void waitForState(aaudio_stream_state_t targetState) { 64 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN; 65 const int kNumTries = 4; // max number of states we expect to transition through 66 for (int i = 0; ((i < kNumTries) && (state != targetState)); i++) { 67 EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream(), 68 state, 69 &state, 70 500 * NANOS_PER_MILLISECOND)); 71 } 72 } 73 flushStream()74 void flushStream() { 75 streamCommand(&AAudioStream_requestFlush, 76 AAUDIO_STREAM_STATE_FLUSHING, AAUDIO_STREAM_STATE_FLUSHED); 77 } 78 builder()79 AAudioStreamBuilder* builder() const { return mBuilder; } stream()80 AAudioStream* stream() const { return mStream; } actual()81 const Parameters& actual() const { return mActual; } framesPerBurst()82 int32_t framesPerBurst() const { return mFramesPerBurst; } 83 84 protected: 85 StreamBuilderHelper(aaudio_direction_t direction, int32_t sampleRate, 86 int32_t channelCount, aaudio_format_t dataFormat, 87 aaudio_sharing_mode_t sharingMode, aaudio_performance_mode_t perfMode); 88 ~StreamBuilderHelper(); 89 90 typedef aaudio_result_t (StreamCommand)(AAudioStream*); 91 void streamCommand( 92 StreamCommand cmd, aaudio_stream_state_t fromState, aaudio_stream_state_t toState); 93 94 static const std::map<aaudio_performance_mode_t, int64_t> sMaxFramesPerBurstMs; 95 const aaudio_direction_t mDirection; 96 const Parameters mRequested; 97 Parameters mActual; 98 int32_t mFramesPerBurst; 99 AAudioStreamBuilder *mBuilder; 100 AAudioStream *mStream; 101 }; 102 103 class InputStreamBuilderHelper : public StreamBuilderHelper { 104 public: 105 InputStreamBuilderHelper( 106 aaudio_sharing_mode_t requestedSharingMode, 107 aaudio_performance_mode_t requestedPerfMode, 108 aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_FLOAT); 109 }; 110 111 class OutputStreamBuilderHelper : public StreamBuilderHelper { 112 public: 113 OutputStreamBuilderHelper( 114 aaudio_sharing_mode_t requestedSharingMode, 115 aaudio_performance_mode_t requestedPerfMode, 116 aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_I16); 117 void initBuilder(); 118 void createAndVerifyStream(bool *success); 119 120 private: 121 const int32_t kBufferCapacityFrames = 2000; 122 }; 123 124 125 #define LIB_AAUDIO_NAME "libaaudio.so" 126 #define FUNCTION_IS_MMAP "AAudioStream_isMMapUsed" 127 #define FUNCTION_SET_MMAP_POLICY "AAudio_setMMapPolicy" 128 #define FUNCTION_GET_MMAP_POLICY "AAudio_getMMapPolicy" 129 130 enum { 131 AAUDIO_POLICY_UNSPECIFIED = 0, 132 /* These definitions are from aaudio/AAudioTesting.h */ 133 AAUDIO_POLICY_NEVER = 1, 134 AAUDIO_POLICY_AUTO = 2, 135 AAUDIO_POLICY_ALWAYS = 3 136 }; 137 typedef int32_t aaudio_policy_t; 138 139 /** 140 * Call some AAudio test routines that are not part of the normal API. 141 */ 142 class AAudioExtensions { 143 public: 144 AAudioExtensions(); 145 isPolicyEnabled(int32_t policy)146 static bool isPolicyEnabled(int32_t policy) { 147 return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS); 148 } 149 getInstance()150 static AAudioExtensions &getInstance() { 151 static AAudioExtensions instance; 152 return instance; 153 } 154 getMMapPolicyProperty()155 static int getMMapPolicyProperty() { 156 return getIntegerProperty("aaudio.mmap_policy", AAUDIO_POLICY_UNSPECIFIED); 157 } 158 getMMapPolicy()159 aaudio_policy_t getMMapPolicy() { 160 if (!mFunctionsLoaded) return -1; 161 return mAAudio_getMMapPolicy(); 162 } 163 setMMapPolicy(aaudio_policy_t policy)164 int32_t setMMapPolicy(aaudio_policy_t policy) { 165 if (!mFunctionsLoaded) return -1; 166 return mAAudio_setMMapPolicy(policy); 167 } 168 isMMapUsed(AAudioStream * aaudioStream)169 bool isMMapUsed(AAudioStream *aaudioStream) { 170 if (!mFunctionsLoaded) return false; 171 return mAAudioStream_isMMap(aaudioStream); 172 } 173 setMMapEnabled(bool enabled)174 int32_t setMMapEnabled(bool enabled) { 175 return setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER); 176 } 177 isMMapEnabled()178 bool isMMapEnabled() { 179 return isPolicyEnabled(mAAudio_getMMapPolicy()); 180 } 181 isMMapSupported()182 bool isMMapSupported() const { 183 return mMMapSupported; 184 } 185 isMMapExclusiveSupported()186 bool isMMapExclusiveSupported() const { 187 return mMMapExclusiveSupported; 188 } 189 190 private: 191 192 static int getIntegerProperty(const char *name, int defaultValue); 193 194 /** 195 * Load some AAudio test functions. 196 * This should only be called once from the constructor. 197 * @return true if it succeeds 198 */ 199 bool loadLibrary(); 200 201 bool mFunctionsLoaded = false; 202 void *mLibHandle = nullptr; 203 bool (*mAAudioStream_isMMap)(AAudioStream *stream) = nullptr; 204 int32_t (*mAAudio_setMMapPolicy)(aaudio_policy_t policy) = nullptr; 205 aaudio_policy_t (*mAAudio_getMMapPolicy)() = nullptr; 206 207 const bool mMMapSupported; 208 const bool mMMapExclusiveSupported; 209 }; 210 211 #endif // CTS_MEDIA_TEST_AAUDIO_UTILS_H 212