• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
119   private:
120     const int32_t kBufferCapacityFrames = 2000;
121 };
122 
123 
124 #define LIB_AAUDIO_NAME          "libaaudio.so"
125 #define FUNCTION_IS_MMAP         "AAudioStream_isMMapUsed"
126 #define FUNCTION_SET_MMAP_POLICY "AAudio_setMMapPolicy"
127 #define FUNCTION_GET_MMAP_POLICY "AAudio_getMMapPolicy"
128 
129 enum {
130     AAUDIO_POLICY_UNSPECIFIED = 0,
131 /* These definitions are from aaudio/AAudioTesting.h */
132     AAUDIO_POLICY_NEVER = 1,
133     AAUDIO_POLICY_AUTO = 2,
134     AAUDIO_POLICY_ALWAYS = 3
135 };
136 typedef int32_t aaudio_policy_t;
137 
138 /**
139  * Call some AAudio test routines that are not part of the normal API.
140  */
141 class AAudioExtensions {
142 public:
143     AAudioExtensions();
144 
isPolicyEnabled(int32_t policy)145     static bool isPolicyEnabled(int32_t policy) {
146         return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS);
147     }
148 
getInstance()149     static AAudioExtensions &getInstance() {
150         static AAudioExtensions instance;
151         return instance;
152     }
153 
getMMapPolicyProperty()154     static int getMMapPolicyProperty() {
155         return getIntegerProperty("aaudio.mmap_policy", AAUDIO_POLICY_UNSPECIFIED);
156     }
157 
getMMapPolicy()158     aaudio_policy_t getMMapPolicy() {
159         if (!mFunctionsLoaded) return -1;
160         return mAAudio_getMMapPolicy();
161     }
162 
setMMapPolicy(aaudio_policy_t policy)163     int32_t setMMapPolicy(aaudio_policy_t policy) {
164         if (!mFunctionsLoaded) return -1;
165         return mAAudio_setMMapPolicy(policy);
166     }
167 
isMMapUsed(AAudioStream * aaudioStream)168     bool isMMapUsed(AAudioStream *aaudioStream) {
169         if (!mFunctionsLoaded) return false;
170         return mAAudioStream_isMMap(aaudioStream);
171     }
172 
setMMapEnabled(bool enabled)173     int32_t setMMapEnabled(bool enabled) {
174         return setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER);
175     }
176 
isMMapEnabled()177     bool isMMapEnabled() {
178         return isPolicyEnabled(mAAudio_getMMapPolicy());
179     }
180 
isMMapSupported()181     bool isMMapSupported() const {
182         return mMMapSupported;
183     }
184 
isMMapExclusiveSupported()185     bool isMMapExclusiveSupported() const {
186         return mMMapExclusiveSupported;
187     }
188 
189 private:
190 
191     static int getIntegerProperty(const char *name, int defaultValue);
192 
193     /**
194      * Load some AAudio test functions.
195      * This should only be called once from the constructor.
196      * @return true if it succeeds
197      */
198     bool loadLibrary();
199 
200     bool      mFunctionsLoaded = false;
201     void     *mLibHandle = nullptr;
202     bool    (*mAAudioStream_isMMap)(AAudioStream *stream) = nullptr;
203     int32_t (*mAAudio_setMMapPolicy)(aaudio_policy_t policy) = nullptr;
204     aaudio_policy_t (*mAAudio_getMMapPolicy)() = nullptr;
205 
206     const bool   mMMapSupported;
207     const bool   mMMapExclusiveSupported;
208 };
209 
210 #endif  // CTS_MEDIA_TEST_AAUDIO_UTILS_H
211