xref: /aosp_15_r20/cts/tests/tests/media/audio/jni/appendix-b-1-1-buffer-queue.cpp (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker  *
4*b7c941bbSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*b7c941bbSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*b7c941bbSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*b7c941bbSAndroid Build Coastguard Worker  *
8*b7c941bbSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*b7c941bbSAndroid Build Coastguard Worker  *
10*b7c941bbSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*b7c941bbSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*b7c941bbSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7c941bbSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*b7c941bbSAndroid Build Coastguard Worker  * limitations under the License.
15*b7c941bbSAndroid Build Coastguard Worker  */
16*b7c941bbSAndroid Build Coastguard Worker 
17*b7c941bbSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*b7c941bbSAndroid Build Coastguard Worker #define LOG_TAG "OpenSL-ES-Test-B-1-1-Buffer-Queue"
19*b7c941bbSAndroid Build Coastguard Worker 
20*b7c941bbSAndroid Build Coastguard Worker #include "sl-utils.h"
21*b7c941bbSAndroid Build Coastguard Worker 
22*b7c941bbSAndroid Build Coastguard Worker /*
23*b7c941bbSAndroid Build Coastguard Worker  * See https://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.0.1.pdf
24*b7c941bbSAndroid Build Coastguard Worker  * Appendix B.1.1 sample code.
25*b7c941bbSAndroid Build Coastguard Worker  *
26*b7c941bbSAndroid Build Coastguard Worker  * Minor edits made to conform to Android coding style.
27*b7c941bbSAndroid Build Coastguard Worker  *
28*b7c941bbSAndroid Build Coastguard Worker  * Correction to code: SL_IID_VOLUME is now made optional for the mixer.
29*b7c941bbSAndroid Build Coastguard Worker  * It isn't supported on the standard Android mixer, but it is supported on the player.
30*b7c941bbSAndroid Build Coastguard Worker  */
31*b7c941bbSAndroid Build Coastguard Worker 
32*b7c941bbSAndroid Build Coastguard Worker #define MAX_NUMBER_INTERFACES 3
33*b7c941bbSAndroid Build Coastguard Worker 
34*b7c941bbSAndroid Build Coastguard Worker /* Local storage for Audio data in 16 bit words */
35*b7c941bbSAndroid Build Coastguard Worker #define AUDIO_DATA_STORAGE_SIZE 4096
36*b7c941bbSAndroid Build Coastguard Worker 
37*b7c941bbSAndroid Build Coastguard Worker #define AUDIO_DATA_SEGMENTS 8
38*b7c941bbSAndroid Build Coastguard Worker 
39*b7c941bbSAndroid Build Coastguard Worker /* Audio data buffer size in 16 bit words. 8 data segments are used in
40*b7c941bbSAndroid Build Coastguard Worker    this simple example */
41*b7c941bbSAndroid Build Coastguard Worker #define AUDIO_DATA_BUFFER_SIZE (AUDIO_DATA_STORAGE_SIZE / AUDIO_DATA_SEGMENTS)
42*b7c941bbSAndroid Build Coastguard Worker 
43*b7c941bbSAndroid Build Coastguard Worker /* Structure for passing information to callback function */
44*b7c941bbSAndroid Build Coastguard Worker typedef struct  {
45*b7c941bbSAndroid Build Coastguard Worker     SLPlayItf playItf;
46*b7c941bbSAndroid Build Coastguard Worker     SLint16  *pDataBase; // Base address of local audio data storage
47*b7c941bbSAndroid Build Coastguard Worker     SLint16  *pData;     // Current address of local audio data storage
48*b7c941bbSAndroid Build Coastguard Worker     SLuint32  size;
49*b7c941bbSAndroid Build Coastguard Worker } CallbackCntxt;
50*b7c941bbSAndroid Build Coastguard Worker 
51*b7c941bbSAndroid Build Coastguard Worker /* Local storage for Audio data */
52*b7c941bbSAndroid Build Coastguard Worker static SLint16 pcmData[AUDIO_DATA_STORAGE_SIZE];
53*b7c941bbSAndroid Build Coastguard Worker 
54*b7c941bbSAndroid Build Coastguard Worker /* Callback for Buffer Queue events */
BufferQueueCallback(SLBufferQueueItf queueItf,void * pContext)55*b7c941bbSAndroid Build Coastguard Worker static void BufferQueueCallback(
56*b7c941bbSAndroid Build Coastguard Worker         SLBufferQueueItf queueItf,
57*b7c941bbSAndroid Build Coastguard Worker         void *pContext)
58*b7c941bbSAndroid Build Coastguard Worker {
59*b7c941bbSAndroid Build Coastguard Worker     SLresult res;
60*b7c941bbSAndroid Build Coastguard Worker     CallbackCntxt *pCntxt = (CallbackCntxt*)pContext;
61*b7c941bbSAndroid Build Coastguard Worker     if (pCntxt->pData < (pCntxt->pDataBase + pCntxt->size)) {
62*b7c941bbSAndroid Build Coastguard Worker         res = (*queueItf)->Enqueue(queueItf, (void *)pCntxt->pData,
63*b7c941bbSAndroid Build Coastguard Worker                 sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
64*b7c941bbSAndroid Build Coastguard Worker         ALOGE_IF(res != SL_RESULT_SUCCESS, "error: %s", android::getSLErrStr(res));
65*b7c941bbSAndroid Build Coastguard Worker         /* Increase data pointer by buffer size */
66*b7c941bbSAndroid Build Coastguard Worker         pCntxt->pData += AUDIO_DATA_BUFFER_SIZE;
67*b7c941bbSAndroid Build Coastguard Worker     }
68*b7c941bbSAndroid Build Coastguard Worker }
69*b7c941bbSAndroid Build Coastguard Worker 
70*b7c941bbSAndroid Build Coastguard Worker /* Play some music from a buffer queue */
TestPlayMusicBufferQueue(SLObjectItf sl)71*b7c941bbSAndroid Build Coastguard Worker static void TestPlayMusicBufferQueue(SLObjectItf sl)
72*b7c941bbSAndroid Build Coastguard Worker {
73*b7c941bbSAndroid Build Coastguard Worker     SLEngineItf EngineItf;
74*b7c941bbSAndroid Build Coastguard Worker 
75*b7c941bbSAndroid Build Coastguard Worker     SLresult res;
76*b7c941bbSAndroid Build Coastguard Worker 
77*b7c941bbSAndroid Build Coastguard Worker     SLDataSource audioSource;
78*b7c941bbSAndroid Build Coastguard Worker     SLDataLocator_BufferQueue bufferQueue;
79*b7c941bbSAndroid Build Coastguard Worker     SLDataFormat_PCM pcm;
80*b7c941bbSAndroid Build Coastguard Worker 
81*b7c941bbSAndroid Build Coastguard Worker     SLDataSink audioSink;
82*b7c941bbSAndroid Build Coastguard Worker     SLDataLocator_OutputMix locator_outputmix;
83*b7c941bbSAndroid Build Coastguard Worker 
84*b7c941bbSAndroid Build Coastguard Worker     SLObjectItf player;
85*b7c941bbSAndroid Build Coastguard Worker     SLPlayItf playItf;
86*b7c941bbSAndroid Build Coastguard Worker     SLBufferQueueItf bufferQueueItf;
87*b7c941bbSAndroid Build Coastguard Worker     SLBufferQueueState state;
88*b7c941bbSAndroid Build Coastguard Worker 
89*b7c941bbSAndroid Build Coastguard Worker     SLObjectItf OutputMix;
90*b7c941bbSAndroid Build Coastguard Worker     SLVolumeItf volumeItf;
91*b7c941bbSAndroid Build Coastguard Worker 
92*b7c941bbSAndroid Build Coastguard Worker     int i;
93*b7c941bbSAndroid Build Coastguard Worker 
94*b7c941bbSAndroid Build Coastguard Worker     SLboolean required[MAX_NUMBER_INTERFACES];
95*b7c941bbSAndroid Build Coastguard Worker     SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
96*b7c941bbSAndroid Build Coastguard Worker 
97*b7c941bbSAndroid Build Coastguard Worker     /* Callback context for the buffer queue callback function */
98*b7c941bbSAndroid Build Coastguard Worker     CallbackCntxt cntxt;
99*b7c941bbSAndroid Build Coastguard Worker 
100*b7c941bbSAndroid Build Coastguard Worker     /* Get the SL Engine Interface which is implicit */
101*b7c941bbSAndroid Build Coastguard Worker     res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void *)&EngineItf);
102*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
103*b7c941bbSAndroid Build Coastguard Worker 
104*b7c941bbSAndroid Build Coastguard Worker     /* Initialize arrays required[] and iidArray[] */
105*b7c941bbSAndroid Build Coastguard Worker     for (i = 0; i < MAX_NUMBER_INTERFACES; i++) {
106*b7c941bbSAndroid Build Coastguard Worker         required[i] = SL_BOOLEAN_FALSE;
107*b7c941bbSAndroid Build Coastguard Worker         iidArray[i] = SL_IID_NULL;
108*b7c941bbSAndroid Build Coastguard Worker     }
109*b7c941bbSAndroid Build Coastguard Worker 
110*b7c941bbSAndroid Build Coastguard Worker     // Set arrays required[] and iidArray[] for VOLUME interface
111*b7c941bbSAndroid Build Coastguard Worker     required[0] = SL_BOOLEAN_FALSE; // ANDROID: we don't require this interface
112*b7c941bbSAndroid Build Coastguard Worker     iidArray[0] = SL_IID_VOLUME;
113*b7c941bbSAndroid Build Coastguard Worker 
114*b7c941bbSAndroid Build Coastguard Worker #if 0
115*b7c941bbSAndroid Build Coastguard Worker     const unsigned interfaces = 1;
116*b7c941bbSAndroid Build Coastguard Worker #else
117*b7c941bbSAndroid Build Coastguard Worker 
118*b7c941bbSAndroid Build Coastguard Worker     /* FIXME: Android doesn't properly support optional interfaces (required == false).
119*b7c941bbSAndroid Build Coastguard Worker     [3.1.6] When an application requests explicit interfaces during object creation,
120*b7c941bbSAndroid Build Coastguard Worker     it can flag any interface as required. If an implementation is unable to satisfy
121*b7c941bbSAndroid Build Coastguard Worker     the request for an interface that is not flagged as required (i.e. it is not required),
122*b7c941bbSAndroid Build Coastguard Worker     this will not cause the object to fail creation. On the other hand, if the interface
123*b7c941bbSAndroid Build Coastguard Worker     is flagged as required and the implementation is unable to satisfy the request
124*b7c941bbSAndroid Build Coastguard Worker     for the interface, the object will not be created.
125*b7c941bbSAndroid Build Coastguard Worker     */
126*b7c941bbSAndroid Build Coastguard Worker     const unsigned interfaces = 0;
127*b7c941bbSAndroid Build Coastguard Worker #endif
128*b7c941bbSAndroid Build Coastguard Worker     // Create Output Mix object to be used by player
129*b7c941bbSAndroid Build Coastguard Worker     res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, interfaces,
130*b7c941bbSAndroid Build Coastguard Worker             iidArray, required);
131*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
132*b7c941bbSAndroid Build Coastguard Worker 
133*b7c941bbSAndroid Build Coastguard Worker     // Realizing the Output Mix object in synchronous mode.
134*b7c941bbSAndroid Build Coastguard Worker     res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);
135*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
136*b7c941bbSAndroid Build Coastguard Worker 
137*b7c941bbSAndroid Build Coastguard Worker     volumeItf = NULL; // ANDROID: Volume interface on mix object may not be supported
138*b7c941bbSAndroid Build Coastguard Worker     res = (*OutputMix)->GetInterface(OutputMix, SL_IID_VOLUME,
139*b7c941bbSAndroid Build Coastguard Worker             (void *)&volumeItf);
140*b7c941bbSAndroid Build Coastguard Worker 
141*b7c941bbSAndroid Build Coastguard Worker     /* Setup the data source structure for the buffer queue */
142*b7c941bbSAndroid Build Coastguard Worker     bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
143*b7c941bbSAndroid Build Coastguard Worker     bufferQueue.numBuffers = 4; /* Four buffers in our buffer queue */
144*b7c941bbSAndroid Build Coastguard Worker 
145*b7c941bbSAndroid Build Coastguard Worker     /* Setup the format of the content in the buffer queue */
146*b7c941bbSAndroid Build Coastguard Worker     pcm.formatType = SL_DATAFORMAT_PCM;
147*b7c941bbSAndroid Build Coastguard Worker     pcm.numChannels = 2;
148*b7c941bbSAndroid Build Coastguard Worker     pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
149*b7c941bbSAndroid Build Coastguard Worker     pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
150*b7c941bbSAndroid Build Coastguard Worker     pcm.containerSize = 16;
151*b7c941bbSAndroid Build Coastguard Worker     pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
152*b7c941bbSAndroid Build Coastguard Worker     pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
153*b7c941bbSAndroid Build Coastguard Worker     audioSource.pFormat = (void *)&pcm;
154*b7c941bbSAndroid Build Coastguard Worker     audioSource.pLocator = (void *)&bufferQueue;
155*b7c941bbSAndroid Build Coastguard Worker 
156*b7c941bbSAndroid Build Coastguard Worker     /* Setup the data sink structure */
157*b7c941bbSAndroid Build Coastguard Worker     locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
158*b7c941bbSAndroid Build Coastguard Worker     locator_outputmix.outputMix = OutputMix;
159*b7c941bbSAndroid Build Coastguard Worker     audioSink.pLocator = (void *)&locator_outputmix;
160*b7c941bbSAndroid Build Coastguard Worker     audioSink.pFormat = NULL;
161*b7c941bbSAndroid Build Coastguard Worker 
162*b7c941bbSAndroid Build Coastguard Worker     /* Initialize the context for Buffer queue callbacks */
163*b7c941bbSAndroid Build Coastguard Worker     cntxt.pDataBase = pcmData;
164*b7c941bbSAndroid Build Coastguard Worker     cntxt.pData = cntxt.pDataBase;
165*b7c941bbSAndroid Build Coastguard Worker     cntxt.size = sizeof(pcmData) / sizeof(pcmData[0]); // ANDROID: Bug
166*b7c941bbSAndroid Build Coastguard Worker 
167*b7c941bbSAndroid Build Coastguard Worker     /* Set arrays required[] and iidArray[] for SEEK interface
168*b7c941bbSAndroid Build Coastguard Worker        (PlayItf is implicit) */
169*b7c941bbSAndroid Build Coastguard Worker     required[0] = SL_BOOLEAN_TRUE;
170*b7c941bbSAndroid Build Coastguard Worker     iidArray[0] = SL_IID_BUFFERQUEUE;
171*b7c941bbSAndroid Build Coastguard Worker 
172*b7c941bbSAndroid Build Coastguard Worker     /* Create the music player */
173*b7c941bbSAndroid Build Coastguard Worker 
174*b7c941bbSAndroid Build Coastguard Worker     res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player,
175*b7c941bbSAndroid Build Coastguard Worker             &audioSource, &audioSink, 1, iidArray, required);
176*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
177*b7c941bbSAndroid Build Coastguard Worker 
178*b7c941bbSAndroid Build Coastguard Worker     /* Realizing the player in synchronous mode. */
179*b7c941bbSAndroid Build Coastguard Worker     res = (*player)->Realize(player, SL_BOOLEAN_FALSE);
180*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
181*b7c941bbSAndroid Build Coastguard Worker 
182*b7c941bbSAndroid Build Coastguard Worker     /* Get seek and play interfaces */
183*b7c941bbSAndroid Build Coastguard Worker     res = (*player)->GetInterface(player, SL_IID_PLAY, (void *)&playItf);
184*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
185*b7c941bbSAndroid Build Coastguard Worker     res = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE,
186*b7c941bbSAndroid Build Coastguard Worker             (void *)&bufferQueueItf);
187*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
188*b7c941bbSAndroid Build Coastguard Worker 
189*b7c941bbSAndroid Build Coastguard Worker     /* Setup to receive buffer queue event callbacks */
190*b7c941bbSAndroid Build Coastguard Worker     res = (*bufferQueueItf)->RegisterCallback(bufferQueueItf,
191*b7c941bbSAndroid Build Coastguard Worker             BufferQueueCallback, &cntxt /* BUG, was NULL */);
192*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
193*b7c941bbSAndroid Build Coastguard Worker 
194*b7c941bbSAndroid Build Coastguard Worker     /* Before we start set volume to -3dB (-300mB) */
195*b7c941bbSAndroid Build Coastguard Worker     if (volumeItf != NULL) { // ANDROID: Volume interface may not be supported.
196*b7c941bbSAndroid Build Coastguard Worker         res = (*volumeItf)->SetVolumeLevel(volumeItf, -300);
197*b7c941bbSAndroid Build Coastguard Worker         CheckErr(res);
198*b7c941bbSAndroid Build Coastguard Worker     }
199*b7c941bbSAndroid Build Coastguard Worker 
200*b7c941bbSAndroid Build Coastguard Worker     /* Enqueue a few buffers to get the ball rolling */
201*b7c941bbSAndroid Build Coastguard Worker     res = (*bufferQueueItf)->Enqueue(bufferQueueItf, cntxt.pData,
202*b7c941bbSAndroid Build Coastguard Worker             sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
203*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
204*b7c941bbSAndroid Build Coastguard Worker     cntxt.pData += AUDIO_DATA_BUFFER_SIZE;
205*b7c941bbSAndroid Build Coastguard Worker     res = (*bufferQueueItf)->Enqueue(bufferQueueItf, cntxt.pData,
206*b7c941bbSAndroid Build Coastguard Worker             sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
207*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
208*b7c941bbSAndroid Build Coastguard Worker     cntxt.pData += AUDIO_DATA_BUFFER_SIZE;
209*b7c941bbSAndroid Build Coastguard Worker     res = (*bufferQueueItf)->Enqueue(bufferQueueItf, cntxt.pData,
210*b7c941bbSAndroid Build Coastguard Worker             sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
211*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
212*b7c941bbSAndroid Build Coastguard Worker     cntxt.pData += AUDIO_DATA_BUFFER_SIZE;
213*b7c941bbSAndroid Build Coastguard Worker 
214*b7c941bbSAndroid Build Coastguard Worker     /* Play the PCM samples using a buffer queue */
215*b7c941bbSAndroid Build Coastguard Worker     res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
216*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
217*b7c941bbSAndroid Build Coastguard Worker 
218*b7c941bbSAndroid Build Coastguard Worker     /* Wait until the PCM data is done playing, the buffer queue callback
219*b7c941bbSAndroid Build Coastguard Worker        will continue to queue buffers until the entire PCM data has been
220*b7c941bbSAndroid Build Coastguard Worker        played. This is indicated by waiting for the count member of the
221*b7c941bbSAndroid Build Coastguard Worker        SLBufferQueueState to go to zero.
222*b7c941bbSAndroid Build Coastguard Worker      */
223*b7c941bbSAndroid Build Coastguard Worker     res = (*bufferQueueItf)->GetState(bufferQueueItf, &state);
224*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
225*b7c941bbSAndroid Build Coastguard Worker 
226*b7c941bbSAndroid Build Coastguard Worker     while (state.count) {
227*b7c941bbSAndroid Build Coastguard Worker         usleep(5 * 1000 /* usec */); // ANDROID: avoid busy waiting
228*b7c941bbSAndroid Build Coastguard Worker         (*bufferQueueItf)->GetState(bufferQueueItf, &state);
229*b7c941bbSAndroid Build Coastguard Worker     }
230*b7c941bbSAndroid Build Coastguard Worker 
231*b7c941bbSAndroid Build Coastguard Worker     /* Make sure player is stopped */
232*b7c941bbSAndroid Build Coastguard Worker     res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
233*b7c941bbSAndroid Build Coastguard Worker     CheckErr(res);
234*b7c941bbSAndroid Build Coastguard Worker 
235*b7c941bbSAndroid Build Coastguard Worker     /* Destroy the player */
236*b7c941bbSAndroid Build Coastguard Worker     (*player)->Destroy(player);
237*b7c941bbSAndroid Build Coastguard Worker 
238*b7c941bbSAndroid Build Coastguard Worker     /* Destroy Output Mix object */
239*b7c941bbSAndroid Build Coastguard Worker     (*OutputMix)->Destroy(OutputMix);
240*b7c941bbSAndroid Build Coastguard Worker }
241*b7c941bbSAndroid Build Coastguard Worker 
Java_android_media_audio_cts_AudioNativeTest_nativeAppendixBBufferQueue(JNIEnv *,jclass)242*b7c941bbSAndroid Build Coastguard Worker extern "C" void Java_android_media_audio_cts_AudioNativeTest_nativeAppendixBBufferQueue(
243*b7c941bbSAndroid Build Coastguard Worker         JNIEnv * /* env */, jclass /* clazz */)
244*b7c941bbSAndroid Build Coastguard Worker {
245*b7c941bbSAndroid Build Coastguard Worker     SLObjectItf engineObject = android::OpenSLEngine();
246*b7c941bbSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(engineObject == NULL, "cannot open OpenSL ES engine");
247*b7c941bbSAndroid Build Coastguard Worker 
248*b7c941bbSAndroid Build Coastguard Worker     TestPlayMusicBufferQueue(engineObject);
249*b7c941bbSAndroid Build Coastguard Worker     android::CloseSLEngine(engineObject);
250*b7c941bbSAndroid Build Coastguard Worker }
251