frameworks/av
Revision | accfc6586bce6ff5bceea8969fb5c0d5db6e4f04 (tree) |
---|---|
Time | 2019-01-17 03:58:12 |
Author | android-build-team Robot <android-build-team-robot@goog...> |
Commiter | android-build-team Robot |
Merge cherrypicks of [6072697, 6072075, 6072758, 6072124, 6072885, 6072886, 6072887, 6072580, 6072581, 6072582, 6072583, 6072584, 6072132, 6072195, 6072133, 6072077, 6072134, 6072078, 6072211, 6072762, 6072763, 6072908, 6072909, 6072910, 6072911, 6072912, 6072913, 6072914, 6072930, 6072212, 6072743] into pi-qpr2-release
Change-Id: I389c3d1ac743425ecd737e2c001e862639f3c990
@@ -38,7 +38,7 @@ fifo_frames_t FifoControllerBase::getFullFramesAvailable() { | ||
38 | 38 | |
39 | 39 | fifo_frames_t FifoControllerBase::getReadIndex() { |
40 | 40 | // % works with non-power of two sizes |
41 | - return (fifo_frames_t) (getReadCounter() % mCapacity); | |
41 | + return (fifo_frames_t) ((uint64_t)getReadCounter() % mCapacity); | |
42 | 42 | } |
43 | 43 | |
44 | 44 | void FifoControllerBase::advanceReadIndex(fifo_frames_t numFrames) { |
@@ -51,7 +51,7 @@ fifo_frames_t FifoControllerBase::getEmptyFramesAvailable() { | ||
51 | 51 | |
52 | 52 | fifo_frames_t FifoControllerBase::getWriteIndex() { |
53 | 53 | // % works with non-power of two sizes |
54 | - return (fifo_frames_t) (getWriteCounter() % mCapacity); | |
54 | + return (fifo_frames_t) ((uint64_t)getWriteCounter() % mCapacity); | |
55 | 55 | } |
56 | 56 | |
57 | 57 | void FifoControllerBase::advanceWriteIndex(fifo_frames_t numFrames) { |
@@ -23,12 +23,12 @@ | ||
23 | 23 | #include "fifo/FifoController.h" |
24 | 24 | |
25 | 25 | using android::fifo_frames_t; |
26 | +using android::fifo_counter_t; | |
26 | 27 | using android::FifoController; |
27 | 28 | using android::FifoBuffer; |
28 | 29 | using android::WrappingBuffer; |
29 | 30 | |
30 | -//void foo() { | |
31 | -TEST(test_fifi_controller, fifo_indices) { | |
31 | +TEST(test_fifo_controller, fifo_indices) { | |
32 | 32 | // Values are arbitrary primes designed to trigger edge cases. |
33 | 33 | constexpr int capacity = 83; |
34 | 34 | constexpr int threshold = 47; |
@@ -73,18 +73,59 @@ TEST(test_fifi_controller, fifo_indices) { | ||
73 | 73 | ASSERT_EQ(threshold - advance2, fifoController.getEmptyFramesAvailable()); |
74 | 74 | } |
75 | 75 | |
76 | +TEST(test_fifo_controller, fifo_wrap_around_zero) { | |
77 | + constexpr int capacity = 7; // arbitrary prime | |
78 | + constexpr int threshold = capacity; | |
79 | + FifoController fifoController(capacity, threshold); | |
80 | + ASSERT_EQ(capacity, fifoController.getCapacity()); | |
81 | + ASSERT_EQ(threshold, fifoController.getThreshold()); | |
82 | + | |
83 | + fifoController.setReadCounter(-10); // a bit less than negative capacity | |
84 | + for (int i = 0; i < 20; i++) { | |
85 | + EXPECT_EQ(i - 10, fifoController.getReadCounter()); | |
86 | + EXPECT_GE(fifoController.getReadIndex(), 0); | |
87 | + EXPECT_LT(fifoController.getReadIndex(), capacity); | |
88 | + fifoController.advanceReadIndex(1); | |
89 | + } | |
90 | + | |
91 | + fifoController.setWriteCounter(-10); | |
92 | + for (int i = 0; i < 20; i++) { | |
93 | + EXPECT_EQ(i - 10, fifoController.getWriteCounter()); | |
94 | + EXPECT_GE(fifoController.getWriteIndex(), 0); | |
95 | + EXPECT_LT(fifoController.getWriteIndex(), capacity); | |
96 | + fifoController.advanceWriteIndex(1); | |
97 | + } | |
98 | +} | |
99 | + | |
100 | + | |
76 | 101 | // TODO consider using a template for other data types. |
102 | + | |
103 | +// Create a big array and then use a region in the middle for the unit tests. | |
104 | +// Then we can scan the rest of the array to see if it got clobbered. | |
105 | +static constexpr fifo_frames_t kBigArraySize = 1024; | |
106 | +static constexpr fifo_frames_t kFifoDataOffset = 128; // starting index of FIFO data | |
107 | +static constexpr int16_t kSafeDataValue = 0x7654; // original value of BigArray | |
108 | + | |
77 | 109 | class TestFifoBuffer { |
78 | 110 | public: |
79 | 111 | explicit TestFifoBuffer(fifo_frames_t capacity, fifo_frames_t threshold = 0) |
80 | - : mFifoBuffer(sizeof(int16_t), capacity) { | |
112 | + : mFifoBuffer(sizeof(int16_t), capacity, | |
113 | + &mReadIndex, | |
114 | + &mWriteIndex, | |
115 | + &mVeryBigArray[kFifoDataOffset]) // address of start of FIFO data | |
116 | + { | |
117 | + | |
118 | + // Assume a frame is one int16_t. | |
81 | 119 | // For reading and writing. |
82 | - mData = new int16_t[capacity]; | |
83 | 120 | if (threshold <= 0) { |
84 | 121 | threshold = capacity; |
85 | 122 | } |
86 | 123 | mFifoBuffer.setThreshold(threshold); |
87 | 124 | mThreshold = threshold; |
125 | + | |
126 | + for (fifo_frames_t i = 0; i < kBigArraySize; i++) { | |
127 | + mVeryBigArray[i] = kSafeDataValue; | |
128 | + } | |
88 | 129 | } |
89 | 130 | |
90 | 131 | void checkMisc() { |
@@ -92,26 +133,70 @@ public: | ||
92 | 133 | ASSERT_EQ(mThreshold, mFifoBuffer.getThreshold()); |
93 | 134 | } |
94 | 135 | |
136 | + void verifyAddressInRange(void *p, void *valid, size_t numBytes) { | |
137 | + uintptr_t p_int = (uintptr_t) p; | |
138 | + uintptr_t valid_int = (uintptr_t) valid; | |
139 | + EXPECT_GE(p_int, valid_int); | |
140 | + EXPECT_LT(p_int, (valid_int + numBytes)); | |
141 | + } | |
142 | + | |
143 | + void verifyStorageIntegrity() { | |
144 | + for (fifo_frames_t i = 0; i < kFifoDataOffset; i++) { | |
145 | + EXPECT_EQ(mVeryBigArray[i], kSafeDataValue); | |
146 | + } | |
147 | + fifo_frames_t firstFrameAfter = kFifoDataOffset + mFifoBuffer.getBufferCapacityInFrames(); | |
148 | + for (fifo_frames_t i = firstFrameAfter; i < kBigArraySize; i++) { | |
149 | + EXPECT_EQ(mVeryBigArray[i], kSafeDataValue); | |
150 | + } | |
151 | + } | |
152 | + | |
95 | 153 | // Verify that the available frames in each part add up correctly. |
96 | - void checkWrappingBuffer() { | |
154 | + void verifyWrappingBuffer() { | |
97 | 155 | WrappingBuffer wrappingBuffer; |
156 | + | |
157 | + | |
158 | + // Does the sum of the two parts match the available value returned? | |
159 | + // For EmptyRoom | |
98 | 160 | fifo_frames_t framesAvailable = |
99 | 161 | mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable(); |
100 | 162 | fifo_frames_t wrapAvailable = mFifoBuffer.getEmptyRoomAvailable(&wrappingBuffer); |
101 | 163 | EXPECT_EQ(framesAvailable, wrapAvailable); |
102 | 164 | fifo_frames_t bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1]; |
103 | 165 | EXPECT_EQ(framesAvailable, bothAvailable); |
104 | - | |
166 | + // For FullData | |
105 | 167 | framesAvailable = |
106 | 168 | mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable(); |
107 | 169 | wrapAvailable = mFifoBuffer.getFullDataAvailable(&wrappingBuffer); |
108 | 170 | EXPECT_EQ(framesAvailable, wrapAvailable); |
109 | 171 | bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1]; |
110 | 172 | EXPECT_EQ(framesAvailable, bothAvailable); |
173 | + | |
174 | + // Are frame counts in legal range? | |
175 | + fifo_frames_t capacity = mFifoBuffer.getBufferCapacityInFrames(); | |
176 | + EXPECT_GE(wrappingBuffer.numFrames[0], 0); | |
177 | + EXPECT_LE(wrappingBuffer.numFrames[0], capacity); | |
178 | + EXPECT_GE(wrappingBuffer.numFrames[1], 0); | |
179 | + EXPECT_LE(wrappingBuffer.numFrames[1], capacity); | |
180 | + | |
181 | + // Are addresses within the FIFO data area? | |
182 | + size_t validBytes = capacity * sizeof(int16_t); | |
183 | + if (wrappingBuffer.numFrames[0]) { | |
184 | + verifyAddressInRange(wrappingBuffer.data[0], mFifoStorage, validBytes); | |
185 | + uint8_t *last = ((uint8_t *)wrappingBuffer.data[0]) | |
186 | + + mFifoBuffer.convertFramesToBytes(wrappingBuffer.numFrames[0]) - 1; | |
187 | + verifyAddressInRange(last, mFifoStorage, validBytes); | |
188 | + } | |
189 | + if (wrappingBuffer.numFrames[1]) { | |
190 | + verifyAddressInRange(wrappingBuffer.data[1], mFifoStorage, validBytes); | |
191 | + uint8_t *last = ((uint8_t *)wrappingBuffer.data[1]) | |
192 | + + mFifoBuffer.convertFramesToBytes(wrappingBuffer.numFrames[1]) - 1; | |
193 | + verifyAddressInRange(last, mFifoStorage, validBytes); | |
194 | + } | |
195 | + | |
111 | 196 | } |
112 | 197 | |
113 | 198 | // Write data but do not overflow. |
114 | - void writeData(fifo_frames_t numFrames) { | |
199 | + void writeMultipleDataFrames(fifo_frames_t numFrames) { | |
115 | 200 | fifo_frames_t framesAvailable = |
116 | 201 | mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable(); |
117 | 202 | fifo_frames_t framesToWrite = std::min(framesAvailable, numFrames); |
@@ -122,8 +207,8 @@ public: | ||
122 | 207 | ASSERT_EQ(framesToWrite, actual); |
123 | 208 | } |
124 | 209 | |
125 | - // Read data but do not underflow. | |
126 | - void verifyData(fifo_frames_t numFrames) { | |
210 | + // Read whatever data is available, Do not underflow. | |
211 | + void verifyMultipleDataFrames(fifo_frames_t numFrames) { | |
127 | 212 | fifo_frames_t framesAvailable = |
128 | 213 | mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable(); |
129 | 214 | fifo_frames_t framesToRead = std::min(framesAvailable, numFrames); |
@@ -134,20 +219,35 @@ public: | ||
134 | 219 | } |
135 | 220 | } |
136 | 221 | |
222 | + // Read specified number of frames | |
223 | + void verifyRequestedData(fifo_frames_t numFrames) { | |
224 | + fifo_frames_t framesAvailable = | |
225 | + mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable(); | |
226 | + ASSERT_LE(numFrames, framesAvailable); | |
227 | + fifo_frames_t framesToRead = std::min(framesAvailable, numFrames); | |
228 | + fifo_frames_t actual = mFifoBuffer.read(mData, framesToRead); | |
229 | + ASSERT_EQ(actual, numFrames); | |
230 | + for (int i = 0; i < actual; i++) { | |
231 | + ASSERT_EQ(mNextVerifyIndex++, mData[i]); | |
232 | + } | |
233 | + } | |
234 | + | |
137 | 235 | // Wrap around the end of the buffer. |
138 | 236 | void checkWrappingWriteRead() { |
139 | 237 | constexpr int frames1 = 43; |
140 | 238 | constexpr int frames2 = 15; |
141 | 239 | |
142 | - writeData(frames1); | |
143 | - checkWrappingBuffer(); | |
144 | - verifyData(frames1); | |
145 | - checkWrappingBuffer(); | |
240 | + writeMultipleDataFrames(frames1); | |
241 | + verifyWrappingBuffer(); | |
242 | + verifyRequestedData(frames1); | |
243 | + verifyWrappingBuffer(); | |
146 | 244 | |
147 | - writeData(frames2); | |
148 | - checkWrappingBuffer(); | |
149 | - verifyData(frames2); | |
150 | - checkWrappingBuffer(); | |
245 | + writeMultipleDataFrames(frames2); | |
246 | + verifyWrappingBuffer(); | |
247 | + verifyRequestedData(frames2); | |
248 | + verifyWrappingBuffer(); | |
249 | + | |
250 | + verifyStorageIntegrity(); | |
151 | 251 | } |
152 | 252 | |
153 | 253 | // Write and Read a specific amount of data. |
@@ -156,10 +256,12 @@ public: | ||
156 | 256 | // Wrap around with the smaller region in the second half. |
157 | 257 | const int frames1 = capacity - 4; |
158 | 258 | const int frames2 = 7; // arbitrary, small |
159 | - writeData(frames1); | |
160 | - verifyData(frames1); | |
161 | - writeData(frames2); | |
162 | - verifyData(frames2); | |
259 | + writeMultipleDataFrames(frames1); | |
260 | + verifyRequestedData(frames1); | |
261 | + writeMultipleDataFrames(frames2); | |
262 | + verifyRequestedData(frames2); | |
263 | + | |
264 | + verifyStorageIntegrity(); | |
163 | 265 | } |
164 | 266 | |
165 | 267 | // Write and Read a specific amount of data. |
@@ -168,10 +270,12 @@ public: | ||
168 | 270 | // Wrap around with the larger region in the second half. |
169 | 271 | const int frames1 = capacity - 4; |
170 | 272 | const int frames2 = capacity - 9; // arbitrary, large |
171 | - writeData(frames1); | |
172 | - verifyData(frames1); | |
173 | - writeData(frames2); | |
174 | - verifyData(frames2); | |
273 | + writeMultipleDataFrames(frames1); | |
274 | + verifyRequestedData(frames1); | |
275 | + writeMultipleDataFrames(frames2); | |
276 | + verifyRequestedData(frames2); | |
277 | + | |
278 | + verifyStorageIntegrity(); | |
175 | 279 | } |
176 | 280 | |
177 | 281 | // Randomly read or write up to the maximum amount of data. |
@@ -180,30 +284,67 @@ public: | ||
180 | 284 | fifo_frames_t framesEmpty = |
181 | 285 | mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable(); |
182 | 286 | fifo_frames_t numFrames = (fifo_frames_t)(drand48() * framesEmpty); |
183 | - writeData(numFrames); | |
287 | + writeMultipleDataFrames(numFrames); | |
184 | 288 | |
185 | 289 | fifo_frames_t framesFull = |
186 | 290 | mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable(); |
187 | 291 | numFrames = (fifo_frames_t)(drand48() * framesFull); |
188 | - verifyData(numFrames); | |
292 | + verifyMultipleDataFrames(numFrames); | |
189 | 293 | } |
294 | + | |
295 | + verifyStorageIntegrity(); | |
296 | + } | |
297 | + | |
298 | + // Write and Read a specific amount of data. | |
299 | + void checkNegativeCounters() { | |
300 | + fifo_counter_t counter = -9876; | |
301 | + mFifoBuffer.setWriteCounter(counter); | |
302 | + mFifoBuffer.setReadCounter(counter); | |
303 | + checkWrappingWriteRead(); | |
304 | + } | |
305 | + | |
306 | + // Wrap over the boundary at 0x7FFFFFFFFFFFFFFF | |
307 | + // Note that the behavior of a signed overflow is technically undefined. | |
308 | + void checkHalfWrap() { | |
309 | + fifo_counter_t counter = INT64_MAX - 10; | |
310 | + mFifoBuffer.setWriteCounter(counter); | |
311 | + mFifoBuffer.setReadCounter(counter); | |
312 | + ASSERT_GT(mFifoBuffer.getWriteCounter(), 0); | |
313 | + checkWrappingWriteRead(); | |
314 | + ASSERT_LT(mFifoBuffer.getWriteCounter(), 0); // did we wrap past INT64_MAX? | |
315 | + } | |
316 | + | |
317 | + // Wrap over the boundary at 0xFFFFFFFFFFFFFFFF | |
318 | + void checkFullWrap() { | |
319 | + fifo_counter_t counter = -10; | |
320 | + mFifoBuffer.setWriteCounter(counter); | |
321 | + mFifoBuffer.setReadCounter(counter); | |
322 | + ASSERT_LT(mFifoBuffer.getWriteCounter(), 0); | |
323 | + writeMultipleDataFrames(20); | |
324 | + ASSERT_GT(mFifoBuffer.getWriteCounter(), 0); // did we wrap past zero? | |
325 | + verifyStorageIntegrity(); | |
190 | 326 | } |
191 | 327 | |
192 | 328 | FifoBuffer mFifoBuffer; |
193 | - int16_t *mData; | |
194 | 329 | fifo_frames_t mNextWriteIndex = 0; |
195 | 330 | fifo_frames_t mNextVerifyIndex = 0; |
196 | 331 | fifo_frames_t mThreshold; |
332 | + | |
333 | + fifo_counter_t mReadIndex = 0; | |
334 | + fifo_counter_t mWriteIndex = 0; | |
335 | + int16_t mVeryBigArray[kBigArraySize]; // Use the middle of this array for the FIFO. | |
336 | + int16_t *mFifoStorage = &mVeryBigArray[kFifoDataOffset]; // Start here for storage. | |
337 | + int16_t mData[kBigArraySize]{}; | |
197 | 338 | }; |
198 | 339 | |
199 | -TEST(test_fifo_buffer, fifo_read_write) { | |
340 | +TEST(test_fifo_buffer, fifo_write_read) { | |
200 | 341 | constexpr int capacity = 51; // arbitrary |
201 | 342 | TestFifoBuffer tester(capacity); |
202 | 343 | tester.checkMisc(); |
203 | 344 | tester.checkWriteRead(); |
204 | 345 | } |
205 | 346 | |
206 | -TEST(test_fifo_buffer, fifo_wrapping_read_write) { | |
347 | +TEST(test_fifo_buffer, fifo_wrapping_write_read) { | |
207 | 348 | constexpr int capacity = 59; // arbitrary, a little bigger this time |
208 | 349 | TestFifoBuffer tester(capacity); |
209 | 350 | tester.checkWrappingWriteRead(); |
@@ -227,3 +368,21 @@ TEST(test_fifo_buffer, fifo_random_threshold) { | ||
227 | 368 | TestFifoBuffer tester(capacity, threshold); |
228 | 369 | tester.checkRandomWriteRead(); |
229 | 370 | } |
371 | + | |
372 | +TEST(test_fifo_buffer, fifo_negative_counters) { | |
373 | + constexpr int capacity = 49; // arbitrary | |
374 | + TestFifoBuffer tester(capacity); | |
375 | + tester.checkNegativeCounters(); | |
376 | +} | |
377 | + | |
378 | +TEST(test_fifo_buffer, fifo_half_wrap) { | |
379 | + constexpr int capacity = 57; // arbitrary | |
380 | + TestFifoBuffer tester(capacity); | |
381 | + tester.checkHalfWrap(); | |
382 | +} | |
383 | + | |
384 | +TEST(test_fifo_buffer, fifo_full_wrap) { | |
385 | + constexpr int capacity = 57; // arbitrary | |
386 | + TestFifoBuffer tester(capacity); | |
387 | + tester.checkFullWrap(); | |
388 | +} |
@@ -54,7 +54,7 @@ void HalDeathHandler::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) | ||
54 | 54 | handler.second(); |
55 | 55 | } |
56 | 56 | ALOGE("HAL server crashed, audio server is restarting"); |
57 | - exit(1); | |
57 | + _exit(1); // Avoid calling atexit handlers, as this code runs on a thread from RPC threadpool. | |
58 | 58 | } |
59 | 59 | |
60 | 60 | } // namespace android |
@@ -3001,6 +3001,8 @@ sp<IEffect> AudioFlinger::createEffect( | ||
3001 | 3001 | } |
3002 | 3002 | |
3003 | 3003 | { |
3004 | + Mutex::Autolock _l(mLock); | |
3005 | + | |
3004 | 3006 | if (!EffectsFactoryHalInterface::isNullUuid(&pDesc->uuid)) { |
3005 | 3007 | // if uuid is specified, request effect descriptor |
3006 | 3008 | lStatus = mEffectsFactoryHal->getDescriptor(&pDesc->uuid, &desc); |
@@ -3056,6 +3058,8 @@ sp<IEffect> AudioFlinger::createEffect( | ||
3056 | 3058 | desc = d; |
3057 | 3059 | } |
3058 | 3060 | } |
3061 | + } | |
3062 | + { | |
3059 | 3063 | |
3060 | 3064 | // Do not allow auxiliary effects on a session different from 0 (output mix) |
3061 | 3065 | if (sessionId != AUDIO_SESSION_OUTPUT_MIX && |