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 <aaudio/AAudio.h> 20 #include <android-base/thread_annotations.h> 21 #include <android/binder_auto_utils.h> 22 #include <android/binder_ibinder.h> 23 #include <dlfcn.h> 24 #include <gtest/gtest.h> 25 #include <sys/system_properties.h> 26 27 #include <atomic> 28 #include <map> 29 #include <mutex> 30 #include <unordered_set> 31 32 #include "test_aaudio.h" // NANOS_PER_MILLISECOND 33 int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC); 34 const char* performanceModeToString(aaudio_performance_mode_t mode); 35 const char* sharingModeToString(aaudio_sharing_mode_t mode); 36 37 static constexpr const char* FEATURE_PLAYBACK = "android.hardware.audio.output"; 38 static constexpr const char* FEATURE_RECORDING = "android.hardware.microphone"; 39 static constexpr const char* FEATURE_LOW_LATENCY = "android.hardware.audio.low_latency"; 40 bool deviceSupportsFeature(const char* feature); 41 int getOutChannelCountMax(); 42 43 const static std::set<aaudio_policy_t> ALL_VALID_POLICIES = {AAUDIO_POLICY_NEVER, 44 AAUDIO_POLICY_AUTO, 45 AAUDIO_POLICY_ALWAYS}; 46 const static std::set<AAudio_DeviceType> ALL_VALID_OUTPUT_DEVICES = { 47 AAUDIO_DEVICE_BUILTIN_EARPIECE, 48 AAUDIO_DEVICE_BUILTIN_SPEAKER, 49 AAUDIO_DEVICE_WIRED_HEADSET, 50 AAUDIO_DEVICE_WIRED_HEADPHONES, 51 AAUDIO_DEVICE_LINE_ANALOG, 52 AAUDIO_DEVICE_LINE_DIGITAL, 53 AAUDIO_DEVICE_BLUETOOTH_SCO, 54 AAUDIO_DEVICE_BLUETOOTH_A2DP, 55 AAUDIO_DEVICE_HDMI, 56 AAUDIO_DEVICE_HDMI_ARC, 57 AAUDIO_DEVICE_HDMI_EARC, 58 AAUDIO_DEVICE_USB_DEVICE, 59 AAUDIO_DEVICE_USB_HEADSET, 60 AAUDIO_DEVICE_USB_ACCESSORY, 61 AAUDIO_DEVICE_DOCK, 62 AAUDIO_DEVICE_DOCK_ANALOG, 63 AAUDIO_DEVICE_FM, 64 AAUDIO_DEVICE_TELEPHONY, 65 AAUDIO_DEVICE_AUX_LINE, 66 AAUDIO_DEVICE_IP, 67 AAUDIO_DEVICE_BUS, 68 AAUDIO_DEVICE_HEARING_AID, 69 AAUDIO_DEVICE_BUILTIN_SPEAKER_SAFE, 70 AAUDIO_DEVICE_REMOTE_SUBMIX, 71 AAUDIO_DEVICE_BLE_HEADSET, 72 AAUDIO_DEVICE_BLE_SPEAKER, 73 AAUDIO_DEVICE_BLE_BROADCAST, 74 }; 75 const static std::set<AAudio_DeviceType> ALL_VALID_INPUT_DEVICES = { 76 AAUDIO_DEVICE_BUILTIN_MIC, AAUDIO_DEVICE_BLUETOOTH_SCO, AAUDIO_DEVICE_WIRED_HEADSET, 77 AAUDIO_DEVICE_HDMI, AAUDIO_DEVICE_TELEPHONY, AAUDIO_DEVICE_DOCK, 78 AAUDIO_DEVICE_DOCK_ANALOG, AAUDIO_DEVICE_USB_ACCESSORY, AAUDIO_DEVICE_USB_DEVICE, 79 AAUDIO_DEVICE_USB_HEADSET, AAUDIO_DEVICE_FM_TUNER, AAUDIO_DEVICE_TV_TUNER, 80 AAUDIO_DEVICE_LINE_ANALOG, AAUDIO_DEVICE_LINE_DIGITAL, AAUDIO_DEVICE_BLUETOOTH_A2DP, 81 AAUDIO_DEVICE_IP, AAUDIO_DEVICE_BUS, AAUDIO_DEVICE_REMOTE_SUBMIX, 82 AAUDIO_DEVICE_BLE_HEADSET, AAUDIO_DEVICE_HDMI_ARC, AAUDIO_DEVICE_HDMI_EARC, 83 }; 84 85 class StreamBuilderHelper { 86 public: 87 struct Parameters { 88 int32_t sampleRate; 89 int32_t channelCount; 90 aaudio_format_t dataFormat; 91 aaudio_sharing_mode_t sharingMode; 92 aaudio_performance_mode_t perfMode; 93 }; 94 95 void initBuilder(); 96 void createAndVerifyStream(bool *success); 97 void close(); 98 startStream()99 void startStream() { 100 streamCommand(&AAudioStream_requestStart, 101 AAUDIO_STREAM_STATE_STARTING, AAUDIO_STREAM_STATE_STARTED); 102 } pauseStream()103 void pauseStream() { 104 streamCommand(&AAudioStream_requestPause, 105 AAUDIO_STREAM_STATE_PAUSING, AAUDIO_STREAM_STATE_PAUSED); 106 } stopStream()107 void stopStream() { 108 streamCommand(&AAudioStream_requestStop, 109 AAUDIO_STREAM_STATE_STOPPING, AAUDIO_STREAM_STATE_STOPPED); 110 } 111 waitForState(aaudio_stream_state_t targetState)112 void waitForState(aaudio_stream_state_t targetState) { 113 aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN; 114 const int kNumTries = 4; // max number of states we expect to transition through 115 for (int i = 0; ((i < kNumTries) && (state != targetState)); i++) { 116 EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream(), 117 state, 118 &state, 119 DEFAULT_STATE_TIMEOUT)); 120 } 121 } 122 flushStream()123 void flushStream() { 124 streamCommand(&AAudioStream_requestFlush, 125 AAUDIO_STREAM_STATE_FLUSHING, AAUDIO_STREAM_STATE_FLUSHED); 126 } 127 builder()128 AAudioStreamBuilder* builder() const { return mBuilder; } stream()129 AAudioStream* stream() const { return mStream; } actual()130 const Parameters& actual() const { return mActual; } framesPerBurst()131 int32_t framesPerBurst() const { return mFramesPerBurst; } 132 133 protected: 134 StreamBuilderHelper(aaudio_direction_t direction, int32_t sampleRate, 135 int32_t channelCount, aaudio_format_t dataFormat, 136 aaudio_sharing_mode_t sharingMode, aaudio_performance_mode_t perfMode); 137 ~StreamBuilderHelper(); 138 139 typedef aaudio_result_t (StreamCommand)(AAudioStream*); 140 void streamCommand( 141 StreamCommand cmd, aaudio_stream_state_t fromState, aaudio_stream_state_t toState); 142 143 static const std::map<aaudio_performance_mode_t, int64_t> sMaxFramesPerBurstMs; 144 static const std::unordered_set<aaudio_format_t> sValidStreamFormats; 145 const aaudio_direction_t mDirection; 146 const Parameters mRequested; 147 Parameters mActual; 148 int32_t mFramesPerBurst; 149 AAudioStreamBuilder *mBuilder; 150 AAudioStream *mStream; 151 152 private: 153 const int32_t kMinValidSampleRate = 8000; // 8 kHz 154 const int32_t kMaxValidSampleRate = 2000000; // 2 MHz 155 const int32_t kMinValidChannelCount = 1; 156 const int32_t kMaxValidChannelCount = getOutChannelCountMax(); 157 }; 158 159 class InputStreamBuilderHelper : public StreamBuilderHelper { 160 public: 161 InputStreamBuilderHelper( 162 aaudio_sharing_mode_t requestedSharingMode, 163 aaudio_performance_mode_t requestedPerfMode, 164 aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_FLOAT, 165 int32_t requestedSampleRate = 48000); 166 }; 167 168 class OutputStreamBuilderHelper : public StreamBuilderHelper { 169 public: 170 OutputStreamBuilderHelper( 171 aaudio_sharing_mode_t requestedSharingMode, 172 aaudio_performance_mode_t requestedPerfMode, 173 aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_I16, 174 int32_t requestSampleRate = 48000); 175 void initBuilder(); 176 177 private: 178 const int32_t kBufferCapacityFrames = 2000; 179 }; 180 181 class AAudioExtensions { 182 public: 183 AAudioExtensions(); 184 isPolicyEnabled(int32_t policy)185 static bool isPolicyEnabled(int32_t policy) { 186 return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS); 187 } 188 getInstance()189 static AAudioExtensions &getInstance() { 190 static AAudioExtensions instance; 191 return instance; 192 } 193 getMMapPolicyProperty()194 static int getMMapPolicyProperty() { 195 return getIntegerProperty("aaudio.mmap_policy", AAUDIO_UNSPECIFIED); 196 } 197 getMMapPolicy()198 aaudio_policy_t getMMapPolicy() { return AAudio_getMMapPolicy(); } 199 setMMapPolicy(aaudio_policy_t policy)200 int32_t setMMapPolicy(aaudio_policy_t policy) { return AAudio_setMMapPolicy(policy); } 201 isMMapUsed(AAudioStream * aaudioStream)202 bool isMMapUsed(AAudioStream* aaudioStream) { return AAudioStream_isMMapUsed(aaudioStream); } 203 setMMapEnabled(bool enabled)204 int32_t setMMapEnabled(bool enabled) { 205 return setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER); 206 } 207 isMMapEnabled()208 bool isMMapEnabled() { return isPolicyEnabled(AAudio_getMMapPolicy()); } 209 isMMapSupported()210 bool isMMapSupported() const { 211 return mMMapSupported; 212 } 213 isMMapExclusiveSupported()214 bool isMMapExclusiveSupported() const { 215 return mMMapExclusiveSupported; 216 } 217 getPlatformMMapPolicy(AAudio_DeviceType device,aaudio_direction_t direction)218 aaudio_policy_t getPlatformMMapPolicy(AAudio_DeviceType device, 219 aaudio_direction_t direction) const { 220 return AAudio_getPlatformMMapPolicy(device, direction); 221 } 222 getPlatformMMapExclusivePolicy(AAudio_DeviceType device,aaudio_direction_t direction)223 aaudio_policy_t getPlatformMMapExclusivePolicy(AAudio_DeviceType device, 224 aaudio_direction_t direction) const { 225 return AAudio_getPlatformMMapExclusivePolicy(device, direction); 226 } 227 isMMapSupportedFor(AAudio_DeviceType deviceType,aaudio_direction_t direction)228 bool isMMapSupportedFor(AAudio_DeviceType deviceType, aaudio_direction_t direction) const { 229 return isPolicyEnabled(getPlatformMMapPolicy(deviceType, direction)); 230 } 231 232 private: 233 234 static int getIntegerProperty(const char *name, int defaultValue); 235 236 bool mMMapSupported; 237 bool mMMapExclusiveSupported; 238 }; 239 240 class AudioServerCrashMonitor { 241 public: getInstance()242 static AudioServerCrashMonitor& getInstance() { 243 static AudioServerCrashMonitor instance; 244 return instance; 245 } 246 247 void linkToDeath(); 248 249 bool isDeathRecipientLinked(); 250 void onAudioServerCrash(); 251 252 private: 253 AudioServerCrashMonitor(); 254 255 ::ndk::SpAIBinder getAudioFlinger_l() REQUIRES(mMutex); 256 257 ::ndk::SpAIBinder mAudioFlinger GUARDED_BY(mMutex); 258 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 259 bool mDeathRecipientLinked = false; 260 261 std::mutex mMutex; 262 }; 263 264 class AAudioCtsBase : public ::testing::Test { 265 protected: 266 void SetUp() override; 267 void TearDown() override; 268 269 private: 270 void checkIfAudioServerCrash(); 271 }; 272 273 bool isIEC61937Supported(); 274 275 bool isEchoReferenceSupported(); 276 277 void enableAudioOutputPermission(); 278 279 void enableAudioHotwordPermission(); 280 281 void disablePermissions(); 282 283 bool isCompressedFormat(aaudio_format_t format); 284 285 int getDeviceTypeFromId(int32_t deviceId); 286 287 #endif // CTS_MEDIA_TEST_AAUDIO_UTILS_H 288