• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 
17 /* OpenSL ES private and global functions not associated with an interface or class */
18 
19 #include "sles_allinclusive.h"
20 
21 
22 /** \brief Return true if the specified interface exists and has been initialized for this object.
23  *  Returns false if the class does not support this kind of interface, or the class supports the
24  *  interface but this particular object has not had the interface exposed at object creation time
25  *  or by DynamicInterface::AddInterface. Note that the return value is not affected by whether
26  *  the application has requested access to the interface with Object::GetInterface. Assumes on
27  *  entry that the object is locked for either shared or exclusive access.
28  */
29 
IsInterfaceInitialized(IObject * this,unsigned MPH)30 bool IsInterfaceInitialized(IObject *this, unsigned MPH)
31 {
32     assert(NULL != this);
33     assert( /* (MPH_MIN <= MPH) && */ (MPH < (unsigned) MPH_MAX));
34     const ClassTable *class__ = this->mClass;
35     assert(NULL != class__);
36     int index;
37     if (0 > (index = class__->mMPH_to_index[MPH])) {
38         return false;
39     }
40     assert(MAX_INDEX >= class__->mInterfaceCount);
41     assert(class__->mInterfaceCount > (unsigned) index);
42     switch (this->mInterfaceStates[index]) {
43     case INTERFACE_EXPOSED:
44     case INTERFACE_ADDED:
45         return true;
46     default:
47         return false;
48     }
49 }
50 
51 
52 /** \brief Map an IObject to it's "object ID" (which is really a class ID) */
53 
IObjectToObjectID(IObject * this)54 SLuint32 IObjectToObjectID(IObject *this)
55 {
56     assert(NULL != this);
57     return this->mClass->mObjectID;
58 }
59 
60 
61 /** \brief Acquire a strong reference to an object.
62  *  Check that object has the specified "object ID" (which is really a class ID) and is in the
63  *  realized state.  If so, then acquire a strong reference to it and return true.
64  *  Otherwise return false.
65  */
66 
AcquireStrongRef(IObject * object,SLuint32 expectedObjectID)67 SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID)
68 {
69     if (NULL == object) {
70         return SL_RESULT_PARAMETER_INVALID;
71     }
72     // NTH additional validity checks on address here
73     SLresult result;
74     object_lock_exclusive(object);
75     SLuint32 actualObjectID = IObjectToObjectID(object);
76     if (expectedObjectID != actualObjectID) {
77         SL_LOGE("object %p has object ID %lu but expected %lu", object, actualObjectID,
78             expectedObjectID);
79         result = SL_RESULT_PARAMETER_INVALID;
80     } else if (SL_OBJECT_STATE_REALIZED != object->mState) {
81         SL_LOGE("object %p with object ID %lu is not realized", object, actualObjectID);
82         result = SL_RESULT_PRECONDITIONS_VIOLATED;
83     } else {
84         ++object->mStrongRefCount;
85         result = SL_RESULT_SUCCESS;
86     }
87     object_unlock_exclusive(object);
88     return result;
89 }
90 
91 
92 /** \brief Release a strong reference to an object.
93  *  Entry condition: the object is locked.
94  *  Exit condition: the object is unlocked.
95  *  Finishes the destroy if needed.
96  */
97 
ReleaseStrongRefAndUnlockExclusive(IObject * object)98 void ReleaseStrongRefAndUnlockExclusive(IObject *object)
99 {
100 #ifdef USE_DEBUG
101     assert(pthread_equal(pthread_self(), object->mOwner));
102 #endif
103     assert(0 < object->mStrongRefCount);
104     if ((0 == --object->mStrongRefCount) && (SL_OBJECT_STATE_DESTROYING == object->mState)) {
105         // FIXME do the destroy here - merge with IDestroy
106         // but can't do this until we move Destroy to the sync thread
107         // as Destroy is now a blocking operation, and to avoid a race
108     } else {
109         object_unlock_exclusive(object);
110     }
111 }
112 
113 
114 /** \brief Release a strong reference to an object.
115  *  Entry condition: the object is unlocked.
116  *  Exit condition: the object is unlocked.
117  *  Finishes the destroy if needed.
118  */
119 
ReleaseStrongRef(IObject * object)120 void ReleaseStrongRef(IObject *object)
121 {
122     assert(NULL != object);
123     object_lock_exclusive(object);
124     ReleaseStrongRefAndUnlockExclusive(object);
125 }
126 
127 
128 /** \brief Convert POSIX pthread error code to OpenSL ES result code */
129 
err_to_result(int err)130 SLresult err_to_result(int err)
131 {
132     if (EAGAIN == err || ENOMEM == err) {
133         return SL_RESULT_RESOURCE_ERROR;
134     }
135     if (0 != err) {
136         return SL_RESULT_INTERNAL_ERROR;
137     }
138     return SL_RESULT_SUCCESS;
139 }
140 
141 
142 /** \brief Check the interface IDs passed into a Create operation */
143 
checkInterfaces(const ClassTable * class__,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired,unsigned * pExposedMask)144 SLresult checkInterfaces(const ClassTable *class__, SLuint32 numInterfaces,
145     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, unsigned *pExposedMask)
146 {
147     assert(NULL != class__ && NULL != pExposedMask);
148     // Initially no interfaces are exposed
149     unsigned exposedMask = 0;
150     const struct iid_vtable *interfaces = class__->mInterfaces;
151     SLuint32 interfaceCount = class__->mInterfaceCount;
152     SLuint32 i;
153     // Expose all implicit interfaces
154     for (i = 0; i < interfaceCount; ++i) {
155         switch (interfaces[i].mInterface) {
156         case INTERFACE_IMPLICIT:
157         case INTERFACE_IMPLICIT_PREREALIZE:
158             // there must be an initialization hook present
159             if (NULL != MPH_init_table[interfaces[i].mMPH].mInit) {
160                 exposedMask |= 1 << i;
161             }
162             break;
163         case INTERFACE_EXPLICIT:
164         case INTERFACE_DYNAMIC:
165         case INTERFACE_UNAVAILABLE:
166         case INTERFACE_EXPLICIT_PREREALIZE:
167             break;
168         default:
169             assert(false);
170             break;
171         }
172     }
173     if (0 < numInterfaces) {
174         if (NULL == pInterfaceIds || NULL == pInterfaceRequired) {
175             return SL_RESULT_PARAMETER_INVALID;
176         }
177         bool anyRequiredButUnsupported = false;
178         // Loop for each requested interface
179         for (i = 0; i < numInterfaces; ++i) {
180             SLInterfaceID iid = pInterfaceIds[i];
181             if (NULL == iid) {
182                 return SL_RESULT_PARAMETER_INVALID;
183             }
184             int MPH, index;
185             if ((0 > (MPH = IID_to_MPH(iid))) ||
186                     // there must be an initialization hook present
187                     (NULL == MPH_init_table[MPH].mInit) ||
188                     (0 > (index = class__->mMPH_to_index[MPH])) ||
189                     (INTERFACE_UNAVAILABLE == interfaces[index].mInterface)) {
190                 // Here if interface was not found, or is not available for this object type
191                 if (pInterfaceRequired[i]) {
192                     // Application said it required the interface, so give up
193                     SL_LOGE("class %s interface %lu required but unavailable MPH=%d",
194                             class__->mName, i, MPH);
195                     anyRequiredButUnsupported = true;
196                 }
197                 // Application said it didn't really need the interface, so ignore with warning
198                 SL_LOGW("class %s interface %lu requested but unavailable MPH=%d",
199                         class__->mName, i, MPH);
200                 continue;
201             }
202             // The requested interface was both found and available, so expose it
203             exposedMask |= (1 << index);
204             // Note that we ignore duplicate requests, including equal and aliased IDs
205         }
206         if (anyRequiredButUnsupported) {
207             return SL_RESULT_FEATURE_UNSUPPORTED;
208         }
209     }
210     *pExposedMask = exposedMask;
211     return SL_RESULT_SUCCESS;
212 }
213 
214 
215 /** \brief Helper shared by decoder and encoder */
216 
GetCodecCapabilities(SLuint32 codecId,SLuint32 * pIndex,SLAudioCodecDescriptor * pDescriptor,const CodecDescriptor * codecDescriptors)217 SLresult GetCodecCapabilities(SLuint32 codecId, SLuint32 *pIndex,
218     SLAudioCodecDescriptor *pDescriptor, const CodecDescriptor *codecDescriptors)
219 {
220     if (NULL == pIndex) {
221         return SL_RESULT_PARAMETER_INVALID;
222     }
223     const CodecDescriptor *cd = codecDescriptors;
224     SLuint32 index;
225     if (NULL == pDescriptor) {
226         for (index = 0 ; NULL != cd->mDescriptor; ++cd) {
227             if (cd->mCodecID == codecId) {
228                 ++index;
229             }
230         }
231         *pIndex = index;
232         return SL_RESULT_SUCCESS;
233     }
234     index = *pIndex;
235     for ( ; NULL != cd->mDescriptor; ++cd) {
236         if (cd->mCodecID == codecId) {
237             if (0 == index) {
238                 *pDescriptor = *cd->mDescriptor;
239 #if 0   // Temporary workaround for Khronos bug 6331
240                 if (0 < pDescriptor->numSampleRatesSupported) {
241                     // The malloc is not in the 1.0.1 specification
242                     SLmilliHertz *temp = (SLmilliHertz *) malloc(sizeof(SLmilliHertz) *
243                         pDescriptor->numSampleRatesSupported);
244                     assert(NULL != temp);
245                     memcpy(temp, pDescriptor->pSampleRatesSupported, sizeof(SLmilliHertz) *
246                         pDescriptor->numSampleRatesSupported);
247                     pDescriptor->pSampleRatesSupported = temp;
248                 } else {
249                     pDescriptor->pSampleRatesSupported = NULL;
250                 }
251 #endif
252                 return SL_RESULT_SUCCESS;
253             }
254             --index;
255         }
256     }
257     return SL_RESULT_PARAMETER_INVALID;
258 }
259 
260 
261 /** \brief Check a data locator and make local deep copy */
262 
checkDataLocator(void * pLocator,DataLocator * pDataLocator)263 static SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator)
264 {
265     if (NULL == pLocator) {
266         pDataLocator->mLocatorType = SL_DATALOCATOR_NULL;
267         return SL_RESULT_SUCCESS;
268     }
269     SLresult result;
270     SLuint32 locatorType = *(SLuint32 *)pLocator;
271     switch (locatorType) {
272 
273     case SL_DATALOCATOR_ADDRESS:
274         pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator;
275         // if length is greater than zero, then the address must be non-NULL
276         if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) {
277             SL_LOGE("pAddress is NULL");
278             return SL_RESULT_PARAMETER_INVALID;
279         }
280         break;
281 
282     case SL_DATALOCATOR_BUFFERQUEUE:
283 #ifdef ANDROID
284     // This is an alias that is _not_ converted; the rest of the code must check for both locator
285     // types. That's because it is only an alias for audio players, not audio recorder objects
286     // so we have to remember the distinction.
287     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
288 #endif
289         pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator;
290         // number of buffers must be specified, there is no default value, and must not be excessive
291         if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
292             (pDataLocator->mBufferQueue.numBuffers <= 255))) {
293             SL_LOGE("numBuffers=%u", (unsigned) pDataLocator->mBufferQueue.numBuffers);
294             return SL_RESULT_PARAMETER_INVALID;
295         }
296         break;
297 
298     case SL_DATALOCATOR_IODEVICE:
299         {
300         pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator;
301         SLuint32 deviceType = pDataLocator->mIODevice.deviceType;
302         SLObjectItf device = pDataLocator->mIODevice.device;
303         if (NULL != device) {
304             pDataLocator->mIODevice.deviceID = 0;
305             SLuint32 expectedObjectID;
306             switch (deviceType) {
307             case SL_IODEVICE_LEDARRAY:
308                 expectedObjectID = SL_OBJECTID_LEDDEVICE;
309                 break;
310             case SL_IODEVICE_VIBRA:
311                 expectedObjectID = SL_OBJECTID_VIBRADEVICE;
312                 break;
313             // audio input and audio output cannot be specified via objects
314             case SL_IODEVICE_AUDIOINPUT:
315             // worse yet, an SL_IODEVICE enum constant for audio output does not exist yet
316             // case SL_IODEVICE_AUDIOOUTPUT:
317             default:
318                 SL_LOGE("invalid deviceType %lu", deviceType);
319                 pDataLocator->mIODevice.device = NULL;
320                 return SL_RESULT_PARAMETER_INVALID;
321             }
322             // check that device has the correct object ID and is realized,
323             // and acquire a strong reference to it
324             result = AcquireStrongRef((IObject *) device, expectedObjectID);
325             if (SL_RESULT_SUCCESS != result) {
326                 SL_LOGE("locator type is IODEVICE, but device field %p has wrong object ID or is " \
327                     "not realized", device);
328                 pDataLocator->mIODevice.device = NULL;
329                 return result;
330             }
331         } else {
332             SLuint32 deviceID = pDataLocator->mIODevice.deviceID;
333             switch (deviceType) {
334             case SL_IODEVICE_LEDARRAY:
335                 if (SL_DEFAULTDEVICEID_LED != deviceID) {
336                     SL_LOGE("invalid LED deviceID %lu", deviceID);
337                     return SL_RESULT_PARAMETER_INVALID;
338                 }
339                 break;
340             case SL_IODEVICE_VIBRA:
341                 if (SL_DEFAULTDEVICEID_VIBRA != deviceID) {
342                     SL_LOGE("invalid vibra deviceID %lu", deviceID);
343                     return SL_RESULT_PARAMETER_INVALID;
344                 }
345                 break;
346             case SL_IODEVICE_AUDIOINPUT:
347                 if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) {
348                     SL_LOGE("invalid audio input deviceID %lu", deviceID);
349                     return SL_RESULT_PARAMETER_INVALID;
350                 }
351                 break;
352             default:
353                 SL_LOGE("invalid deviceType %lu", deviceType);
354                 return SL_RESULT_PARAMETER_INVALID;
355             }
356         }
357         }
358         break;
359 
360     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
361         pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator;
362         if (0 == pDataLocator->mMIDIBufferQueue.tpqn) {
363             pDataLocator->mMIDIBufferQueue.tpqn = 192;
364         }
365         // number of buffers must be specified, there is no default value, and must not be excessive
366         if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) &&
367             (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) {
368             SL_LOGE("invalid MIDI buffer queue");
369             return SL_RESULT_PARAMETER_INVALID;
370         }
371         break;
372 
373     case SL_DATALOCATOR_OUTPUTMIX:
374         pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator;
375         // check that output mix object has the correct object ID and is realized,
376         // and acquire a strong reference to it
377         result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix,
378             SL_OBJECTID_OUTPUTMIX);
379         if (SL_RESULT_SUCCESS != result) {
380             SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does not " \
381                 "refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \
382                 pDataLocator->mOutputMix.outputMix);
383             pDataLocator->mOutputMix.outputMix = NULL;
384             return result;
385         }
386         break;
387 
388     case SL_DATALOCATOR_URI:
389         {
390         pDataLocator->mURI = *(SLDataLocator_URI *)pLocator;
391         if (NULL == pDataLocator->mURI.URI) {
392             SL_LOGE("invalid URI");
393             return SL_RESULT_PARAMETER_INVALID;
394         }
395         // NTH verify URI address for validity
396         size_t len = strlen((const char *) pDataLocator->mURI.URI);
397         SLchar *myURI = (SLchar *) malloc(len + 1);
398         if (NULL == myURI) {
399             pDataLocator->mURI.URI = NULL;
400             return SL_RESULT_MEMORY_FAILURE;
401         }
402         memcpy(myURI, pDataLocator->mURI.URI, len + 1);
403         // Verify that another thread didn't change the NUL-terminator after we used it
404         // to determine length of string to copy. It's OK if the string became shorter.
405         if ('\0' != myURI[len]) {
406             free(myURI);
407             pDataLocator->mURI.URI = NULL;
408             return SL_RESULT_PARAMETER_INVALID;
409         }
410         pDataLocator->mURI.URI = myURI;
411         }
412         break;
413 
414 #ifdef ANDROID
415     case SL_DATALOCATOR_ANDROIDFD:
416         {
417         pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator;
418         SL_LOGV("Data locator FD: fd=%ld offset=%lld length=%lld", pDataLocator->mFD.fd,
419                 pDataLocator->mFD.offset, pDataLocator->mFD.length);
420         // NTH check against process fd limit
421         if (0 > pDataLocator->mFD.fd) {
422             return SL_RESULT_PARAMETER_INVALID;
423         }
424         }
425         break;
426 #endif
427 
428     default:
429         SL_LOGE("invalid locatorType %lu", locatorType);
430         return SL_RESULT_PARAMETER_INVALID;
431     }
432 
433     // Verify that another thread didn't change the locatorType field after we used it
434     // to determine sizeof struct to copy.
435     if (locatorType != pDataLocator->mLocatorType) {
436         return SL_RESULT_PARAMETER_INVALID;
437     }
438     return SL_RESULT_SUCCESS;
439 }
440 
441 
442 /** \brief Free the local deep copy of a data locator */
443 
freeDataLocator(DataLocator * pDataLocator)444 static void freeDataLocator(DataLocator *pDataLocator)
445 {
446     switch (pDataLocator->mLocatorType) {
447     case SL_DATALOCATOR_URI:
448         if (NULL != pDataLocator->mURI.URI) {
449             free(pDataLocator->mURI.URI);
450             pDataLocator->mURI.URI = NULL;
451         }
452         pDataLocator->mURI.URI = NULL;
453         break;
454     case SL_DATALOCATOR_IODEVICE:
455         if (NULL != pDataLocator->mIODevice.device) {
456             ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device);
457             pDataLocator->mIODevice.device = NULL;
458         }
459         break;
460     case SL_DATALOCATOR_OUTPUTMIX:
461         if (NULL != pDataLocator->mOutputMix.outputMix) {
462             ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix);
463             pDataLocator->mOutputMix.outputMix = NULL;
464         }
465         break;
466     default:
467         break;
468     }
469 }
470 
471 
472 /** \brief Check a data format and make local deep copy */
473 
checkDataFormat(void * pFormat,DataFormat * pDataFormat)474 static SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat)
475 {
476     SLresult result = SL_RESULT_SUCCESS;
477 
478     if (NULL == pFormat) {
479         pDataFormat->mFormatType = SL_DATAFORMAT_NULL;
480     } else {
481         SLuint32 formatType = *(SLuint32 *)pFormat;
482         switch (formatType) {
483 
484         case SL_DATAFORMAT_PCM:
485             pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
486             do {
487 
488                 // check the channel count
489                 switch (pDataFormat->mPCM.numChannels) {
490                 case 1:     // mono
491                 case 2:     // stereo
492                     break;
493                 case 0:     // unknown
494                     result = SL_RESULT_PARAMETER_INVALID;
495                     break;
496                 default:    // multi-channel
497                     result = SL_RESULT_CONTENT_UNSUPPORTED;
498                     break;
499                 }
500                 if (SL_RESULT_SUCCESS != result) {
501                     SL_LOGE("numChannels=%u", (unsigned) pDataFormat->mPCM.numChannels);
502                     break;
503                 }
504 
505                 // check the sampling rate
506                 switch (pDataFormat->mPCM.samplesPerSec) {
507                 case SL_SAMPLINGRATE_8:
508                 case SL_SAMPLINGRATE_11_025:
509                 case SL_SAMPLINGRATE_12:
510                 case SL_SAMPLINGRATE_16:
511                 case SL_SAMPLINGRATE_22_05:
512                 case SL_SAMPLINGRATE_24:
513                 case SL_SAMPLINGRATE_32:
514                 case SL_SAMPLINGRATE_44_1:
515                 case SL_SAMPLINGRATE_48:
516                 case SL_SAMPLINGRATE_64:
517                 case SL_SAMPLINGRATE_88_2:
518                 case SL_SAMPLINGRATE_96:
519                 case SL_SAMPLINGRATE_192:
520                     break;
521                 case 0:
522                     result = SL_RESULT_PARAMETER_INVALID;
523                     break;
524                 default:
525                     result = SL_RESULT_CONTENT_UNSUPPORTED;
526                     break;
527                 }
528                 if (SL_RESULT_SUCCESS != result) {
529                     SL_LOGE("samplesPerSec=%u", (unsigned) pDataFormat->mPCM.samplesPerSec);
530                     break;
531                 }
532 
533                 // check the sample bit depth
534                 switch (pDataFormat->mPCM.bitsPerSample) {
535                 case SL_PCMSAMPLEFORMAT_FIXED_8:
536                 case SL_PCMSAMPLEFORMAT_FIXED_16:
537                     break;
538                 case SL_PCMSAMPLEFORMAT_FIXED_20:
539                 case SL_PCMSAMPLEFORMAT_FIXED_24:
540                 case SL_PCMSAMPLEFORMAT_FIXED_28:
541                 case SL_PCMSAMPLEFORMAT_FIXED_32:
542                     result = SL_RESULT_CONTENT_UNSUPPORTED;
543                     break;
544                 default:
545                     result = SL_RESULT_PARAMETER_INVALID;
546                     break;
547                 }
548                 if (SL_RESULT_SUCCESS != result) {
549                     SL_LOGE("bitsPerSample=%u", (unsigned) pDataFormat->mPCM.bitsPerSample);
550                     break;
551                 }
552 
553                 // check the container bit depth
554                 if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
555                     result = SL_RESULT_PARAMETER_INVALID;
556                 } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) {
557                     result = SL_RESULT_CONTENT_UNSUPPORTED;
558                 }
559                 if (SL_RESULT_SUCCESS != result) {
560                     SL_LOGE("containerSize=%u, bitsPerSample=%u",
561                             (unsigned) pDataFormat->mPCM.containerSize,
562                             (unsigned) pDataFormat->mPCM.bitsPerSample);
563                     break;
564                 }
565 
566                 // check the channel mask
567                 switch (pDataFormat->mPCM.channelMask) {
568                 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT:
569                     if (2 != pDataFormat->mPCM.numChannels) {
570                         result = SL_RESULT_PARAMETER_INVALID;
571                     }
572                     break;
573                 case SL_SPEAKER_FRONT_LEFT:
574                 case SL_SPEAKER_FRONT_RIGHT:
575                 case SL_SPEAKER_FRONT_CENTER:
576                     if (1 != pDataFormat->mPCM.numChannels) {
577                         result = SL_RESULT_PARAMETER_INVALID;
578                     }
579                     break;
580                 case 0:
581                     pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ?
582                         SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER;
583                     break;
584                 default:
585                     result = SL_RESULT_PARAMETER_INVALID;
586                     break;
587                 }
588                 if (SL_RESULT_SUCCESS != result) {
589                     SL_LOGE("channelMask=0x%lx numChannels=%lu", pDataFormat->mPCM.channelMask,
590                         pDataFormat->mPCM.numChannels);
591                     break;
592                 }
593 
594                 // check the endianness / byte order
595                 switch (pDataFormat->mPCM.endianness) {
596                 case SL_BYTEORDER_LITTLEENDIAN:
597                 case SL_BYTEORDER_BIGENDIAN:
598                     break;
599                 // native is proposed but not yet in spec
600                 default:
601                     result = SL_RESULT_PARAMETER_INVALID;
602                     break;
603                 }
604                 if (SL_RESULT_SUCCESS != result) {
605                     SL_LOGE("endianness=%u", (unsigned) pDataFormat->mPCM.endianness);
606                     break;
607                 }
608 
609                 // here if all checks passed successfully
610 
611             } while(0);
612             break;
613 
614         case SL_DATAFORMAT_MIME:
615             pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
616             if (NULL != pDataFormat->mMIME.mimeType) {
617                 // NTH check address for validity
618                 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
619                 SLchar *myMIME = (SLchar *) malloc(len + 1);
620                 if (NULL == myMIME) {
621                     result = SL_RESULT_MEMORY_FAILURE;
622                 } else {
623                     memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
624                     // make sure MIME string was not modified asynchronously
625                     if ('\0' != myMIME[len]) {
626                         free(myMIME);
627                         myMIME = NULL;
628                         result = SL_RESULT_PRECONDITIONS_VIOLATED;
629                     }
630                 }
631                 pDataFormat->mMIME.mimeType = myMIME;
632             }
633             break;
634 
635         default:
636             result = SL_RESULT_PARAMETER_INVALID;
637             SL_LOGE("formatType=%u", (unsigned) formatType);
638             break;
639 
640         }
641 
642         // make sure format type was not modified asynchronously
643         if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
644             result = SL_RESULT_PRECONDITIONS_VIOLATED;
645         }
646 
647     }
648 
649     return result;
650 }
651 
652 
653 /** \brief Check interface ID compatibility with respect to a particular data locator format */
654 
checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat * pDataLocatorFormat,const ClassTable * class__,unsigned exposedMask)655 SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pDataLocatorFormat,
656         const ClassTable *class__, unsigned exposedMask) {
657     int index;
658     switch (pDataLocatorFormat->mLocator.mLocatorType) {
659     case SL_DATALOCATOR_BUFFERQUEUE:
660 #ifdef ANDROID
661     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
662 #endif
663         // can't request SLSeekItf if data source is a buffer queue
664         index = class__->mMPH_to_index[MPH_SEEK];
665         if (0 <= index) {
666             if (exposedMask & (1 << index)) {
667                 SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source");
668                 return SL_RESULT_FEATURE_UNSUPPORTED;
669             }
670         }
671         // can't request SLMuteSoloItf if data source is a mono buffer queue
672         index = class__->mMPH_to_index[MPH_MUTESOLO];
673         if (0 <= index) {
674             if ((exposedMask & (1 << index)) &&
675                     (SL_DATAFORMAT_PCM == pDataLocatorFormat->mFormat.mFormatType) &&
676                     (1 == pDataLocatorFormat->mFormat.mPCM.numChannels)) {
677                 SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source");
678                 return SL_RESULT_FEATURE_UNSUPPORTED;
679             }
680         }
681         break;
682     default:
683         // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
684         // if the data source is not a buffer queue
685         index = class__->mMPH_to_index[MPH_BUFFERQUEUE];
686 #ifdef ANDROID
687         assert(index == class__->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
688 #endif
689         if (0 <= index) {
690             if (exposedMask & (1 << index)) {
691                 SL_LOGE("can't request SL_IID_BUFFERQUEUE "
692 #ifdef ANDROID
693                         "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
694 #endif
695                         "with a non-buffer queue data source");
696                 return SL_RESULT_FEATURE_UNSUPPORTED;
697             }
698         }
699         break;
700     }
701     return SL_RESULT_SUCCESS;
702 }
703 
704 
705 /** \brief Free the local deep copy of a data format */
706 
freeDataFormat(DataFormat * pDataFormat)707 static void freeDataFormat(DataFormat *pDataFormat)
708 {
709     switch (pDataFormat->mFormatType) {
710     case SL_DATAFORMAT_MIME:
711         if (NULL != pDataFormat->mMIME.mimeType) {
712             free(pDataFormat->mMIME.mimeType);
713             pDataFormat->mMIME.mimeType = NULL;
714         }
715         break;
716     default:
717         break;
718     }
719 }
720 
721 
722 /** \brief Check a data source and make local deep copy */
723 
checkDataSource(const SLDataSource * pDataSrc,DataLocatorFormat * pDataLocatorFormat)724 SLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat)
725 {
726     if (NULL == pDataSrc) {
727         SL_LOGE("pDataSrc NULL");
728         return SL_RESULT_PARAMETER_INVALID;
729     }
730     SLDataSource myDataSrc = *pDataSrc;
731     SLresult result;
732     result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator);
733     if (SL_RESULT_SUCCESS != result) {
734         return result;
735     }
736     switch (pDataLocatorFormat->mLocator.mLocatorType) {
737 
738     case SL_DATALOCATOR_URI:
739     case SL_DATALOCATOR_ADDRESS:
740     case SL_DATALOCATOR_BUFFERQUEUE:
741     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
742 #ifdef ANDROID
743     case SL_DATALOCATOR_ANDROIDFD:
744     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
745 #endif
746         result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat);
747         if (SL_RESULT_SUCCESS != result) {
748             freeDataLocator(&pDataLocatorFormat->mLocator);
749             return result;
750         }
751         break;
752 
753     case SL_DATALOCATOR_NULL:
754     case SL_DATALOCATOR_OUTPUTMIX:
755     default:
756         // invalid but fall through; the invalid locator will be caught later
757         SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType);
758         // keep going
759 
760     case SL_DATALOCATOR_IODEVICE:
761         // for these data locator types, ignore the pFormat as it might be uninitialized
762         pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
763         break;
764     }
765 
766     pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
767     pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
768     return SL_RESULT_SUCCESS;
769 }
770 
771 
772 /** \brief Check a data sink and make local deep copy */
773 
checkDataSink(const SLDataSink * pDataSink,DataLocatorFormat * pDataLocatorFormat,SLuint32 objType)774 SLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat,
775         SLuint32 objType)
776 {
777     if (NULL == pDataSink) {
778         SL_LOGE("pDataSink NULL");
779         return SL_RESULT_PARAMETER_INVALID;
780     }
781     SLDataSink myDataSink = *pDataSink;
782     SLresult result;
783     result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator);
784     if (SL_RESULT_SUCCESS != result) {
785         return result;
786     }
787     switch (pDataLocatorFormat->mLocator.mLocatorType) {
788 
789     case SL_DATALOCATOR_URI:
790     case SL_DATALOCATOR_ADDRESS:
791         result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat);
792         if (SL_RESULT_SUCCESS != result) {
793             freeDataLocator(&pDataLocatorFormat->mLocator);
794             return result;
795         }
796         break;
797 
798     case SL_DATALOCATOR_BUFFERQUEUE:
799 #ifdef ANDROID
800     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
801 #endif
802         if (SL_OBJECTID_AUDIOPLAYER == objType) {
803             SL_LOGE("buffer queue can't be used as data sink for audio player");
804             result = SL_RESULT_PARAMETER_INVALID;
805         } else if (SL_OBJECTID_AUDIORECORDER == objType) {
806 #ifdef ANDROID
807             if (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE !=
808                 pDataLocatorFormat->mLocator.mLocatorType) {
809                 SL_LOGE("audio recorder source locator must be SL_DATALOCATOR_ANDROIDBUFFERQUEUE");
810                 result = SL_RESULT_PARAMETER_INVALID;
811             } else {
812                 result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat);
813             }
814 #else
815             SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType);
816             result = SL_RESULT_PARAMETER_INVALID;
817 #endif
818         }
819         if (SL_RESULT_SUCCESS != result) {
820             freeDataLocator(&pDataLocatorFormat->mLocator);
821             return result;
822         }
823         break;
824 
825     case SL_DATALOCATOR_NULL:
826     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
827     default:
828         // invalid but fall through; the invalid locator will be caught later
829         SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType);
830         // keep going
831 
832     case SL_DATALOCATOR_IODEVICE:
833     case SL_DATALOCATOR_OUTPUTMIX:
834         // for these data locator types, ignore the pFormat as it might be uninitialized
835         pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
836         break;
837     }
838 
839     pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
840     pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
841     return SL_RESULT_SUCCESS;
842 }
843 
844 
845 /** \brief Free the local deep copy of a data locator format */
846 
freeDataLocatorFormat(DataLocatorFormat * dlf)847 void freeDataLocatorFormat(DataLocatorFormat *dlf)
848 {
849     freeDataLocator(&dlf->mLocator);
850     freeDataFormat(&dlf->mFormat);
851 }
852 
853 
854 /* Interface initialization hooks */
855 
856 extern void
857     I3DCommit_init(void *),
858     I3DDoppler_init(void *),
859     I3DGrouping_init(void *),
860     I3DLocation_init(void *),
861     I3DMacroscopic_init(void *),
862     I3DSource_init(void *),
863     IAndroidConfiguration_init(void *),
864     IAndroidEffect_init(void *),
865     IAndroidEffectCapabilities_init(void *),
866     IAndroidEffectSend_init(void *),
867     IAudioDecoderCapabilities_init(void *),
868     IAudioEncoder_init(void *),
869     IAudioEncoderCapabilities_init(void *),
870     IAudioIODeviceCapabilities_init(void *),
871     IBassBoost_init(void *),
872     IBufferQueue_init(void *),
873     IDeviceVolume_init(void *),
874     IDynamicInterfaceManagement_init(void *),
875     IDynamicSource_init(void *),
876     IEffectSend_init(void *),
877     IEngine_init(void *),
878     IEngineCapabilities_init(void *),
879     IEnvironmentalReverb_init(void *),
880     IEqualizer_init(void *),
881     ILEDArray_init(void *),
882     IMIDIMessage_init(void *),
883     IMIDIMuteSolo_init(void *),
884     IMIDITempo_init(void *),
885     IMIDITime_init(void *),
886     IMetadataExtraction_init(void *),
887     IMetadataTraversal_init(void *),
888     IMuteSolo_init(void *),
889     IObject_init(void *),
890     IOutputMix_init(void *),
891     IOutputMixExt_init(void *),
892     IPitch_init(void *),
893     IPlay_init(void *),
894     IPlaybackRate_init(void *),
895     IPrefetchStatus_init(void *),
896     IPresetReverb_init(void *),
897     IRatePitch_init(void *),
898     IRecord_init(void *),
899     ISeek_init(void *),
900     IThreadSync_init(void *),
901     IVibra_init(void *),
902     IVirtualizer_init(void *),
903     IVisualization_init(void *),
904     IVolume_init(void *);
905 
906 extern void
907     I3DGrouping_deinit(void *),
908     IAndroidEffect_deinit(void *),
909     IAndroidEffectCapabilities_deinit(void *),
910     IBassBoost_deinit(void *),
911     IBufferQueue_deinit(void *),
912     IEngine_deinit(void *),
913     IEnvironmentalReverb_deinit(void *),
914     IEqualizer_deinit(void *),
915     IObject_deinit(void *),
916     IPresetReverb_deinit(void *),
917     IThreadSync_deinit(void *),
918     IVirtualizer_deinit(void *);
919 
920 extern bool
921     IAndroidEffectCapabilities_Expose(void *),
922     IBassBoost_Expose(void *),
923     IEnvironmentalReverb_Expose(void *),
924     IEqualizer_Expose(void *),
925     IPresetReverb_Expose(void *),
926     IVirtualizer_Expose(void *);
927 
928 #if !(USE_PROFILES & USE_PROFILES_MUSIC)
929 #define IDynamicSource_init         NULL
930 #define IMetadataExtraction_init    NULL
931 #define IMetadataTraversal_init     NULL
932 #define IVisualization_init         NULL
933 #endif
934 
935 #if !(USE_PROFILES & USE_PROFILES_GAME)
936 #define I3DCommit_init      NULL
937 #define I3DDoppler_init     NULL
938 #define I3DGrouping_init    NULL
939 #define I3DLocation_init    NULL
940 #define I3DMacroscopic_init NULL
941 #define I3DSource_init      NULL
942 #define IMIDIMessage_init   NULL
943 #define IMIDIMuteSolo_init  NULL
944 #define IMIDITempo_init     NULL
945 #define IMIDITime_init      NULL
946 #define IPitch_init         NULL
947 #define IRatePitch_init     NULL
948 #define I3DGrouping_deinit  NULL
949 #endif
950 
951 #if !(USE_PROFILES & USE_PROFILES_BASE)
952 #define IAudioDecoderCapabilities_init   NULL
953 #define IAudioEncoderCapabilities_init   NULL
954 #define IAudioEncoder_init               NULL
955 #define IAudioIODeviceCapabilities_init  NULL
956 #define IDeviceVolume_init               NULL
957 #define IEngineCapabilities_init         NULL
958 #define IThreadSync_init                 NULL
959 #define IThreadSync_deinit               NULL
960 #endif
961 
962 #if !(USE_PROFILES & USE_PROFILES_OPTIONAL)
963 #define ILEDArray_init  NULL
964 #define IVibra_init     NULL
965 #endif
966 
967 #ifndef ANDROID
968 #define IAndroidConfiguration_init        NULL
969 #define IAndroidEffect_init               NULL
970 #define IAndroidEffectCapabilities_init   NULL
971 #define IAndroidEffectSend_init           NULL
972 #define IAndroidEffect_deinit             NULL
973 #define IAndroidEffectCapabilities_deinit NULL
974 #define IAndroidEffectCapabilities_Expose NULL
975 #endif
976 
977 #ifndef USE_OUTPUTMIXEXT
978 #define IOutputMixExt_init  NULL
979 #endif
980 
981 
982 /*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = {
983     { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL, NULL, NULL },
984     { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL, NULL, NULL },
985     { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, I3DGrouping_deinit, NULL, NULL },
986     { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL, NULL, NULL },
987     { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL, NULL, NULL },
988     { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL, NULL, NULL },
989     { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL, NULL, NULL },
990     { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL, NULL, NULL },
991     { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL, NULL, NULL },
992     { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL, NULL,
993         NULL },
994     { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, IBassBoost_deinit, IBassBoost_Expose, NULL },
995     { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, IBufferQueue_deinit, NULL, NULL },
996     { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL, NULL, NULL },
997     { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL, NULL,
998         NULL },
999     { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL, NULL, NULL },
1000     { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL, NULL, NULL },
1001     { /* MPH_ENGINE, */ IEngine_init, NULL, IEngine_deinit, NULL, NULL },
1002     { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL, NULL, NULL },
1003     { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, IEnvironmentalReverb_deinit,
1004         IEnvironmentalReverb_Expose, NULL },
1005     { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, IEqualizer_deinit, IEqualizer_Expose, NULL },
1006     { /* MPH_LED, */ ILEDArray_init, NULL, NULL, NULL, NULL },
1007     { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL, NULL, NULL },
1008     { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL, NULL, NULL },
1009     { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL, NULL, NULL },
1010     { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL, NULL, NULL },
1011     { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL, NULL, NULL },
1012     { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL, NULL, NULL },
1013     { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL, NULL, NULL },
1014     { /* MPH_NULL, */ NULL, NULL, NULL, NULL, NULL },
1015     { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit, NULL, NULL },
1016     { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL, NULL, NULL },
1017     { /* MPH_PITCH, */ IPitch_init, NULL, NULL, NULL, NULL },
1018     { /* MPH_PLAY, */ IPlay_init, NULL, NULL, NULL, NULL },
1019     { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL, NULL, NULL },
1020     { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL },
1021     { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, IPresetReverb_deinit,
1022         IPresetReverb_Expose, NULL },
1023     { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL, NULL, NULL },
1024     { /* MPH_RECORD, */ IRecord_init, NULL, NULL, NULL, NULL },
1025     { /* MPH_SEEK, */ ISeek_init, NULL, NULL, NULL, NULL },
1026     { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, IThreadSync_deinit, NULL, NULL },
1027     { /* MPH_VIBRA, */ IVibra_init, NULL, NULL, NULL, NULL },
1028     { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, IVirtualizer_deinit, IVirtualizer_Expose,
1029         NULL },
1030     { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL },
1031     { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL },
1032     { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL },
1033     { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL },
1034     { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL,
1035         IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL },
1036     { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL },
1037     { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL },
1038     { /* MPH_ANDROIDSIMPLEBUFFERQUEUE, */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL }
1039 };
1040 
1041 
1042 /** \brief Construct a new instance of the specified class, exposing selected interfaces */
1043 
construct(const ClassTable * class__,unsigned exposedMask,SLEngineItf engine)1044 IObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine)
1045 {
1046     IObject *this;
1047     // Do not change this to malloc; we depend on the object being memset to zero
1048     this = (IObject *) calloc(1, class__->mSize);
1049     if (NULL != this) {
1050         SL_LOGV("construct %s at %p", class__->mName, this);
1051         unsigned lossOfControlMask = 0;
1052         // a NULL engine means we are constructing the engine
1053         IEngine *thisEngine = (IEngine *) engine;
1054         if (NULL == thisEngine) {
1055             thisEngine = &((CEngine *) this)->mEngine;
1056         } else {
1057             interface_lock_exclusive(thisEngine);
1058             if (MAX_INSTANCE <= thisEngine->mInstanceCount) {
1059                 SL_LOGE("Too many objects");
1060                 interface_unlock_exclusive(thisEngine);
1061                 free(this);
1062                 return NULL;
1063             }
1064             // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet
1065             ++thisEngine->mInstanceCount;
1066             assert(((unsigned) ~0) != thisEngine->mInstanceMask);
1067             interface_unlock_exclusive(thisEngine);
1068             // const, no lock needed
1069             if (thisEngine->mLossOfControlGlobal) {
1070                 lossOfControlMask = ~0;
1071             }
1072         }
1073         this->mLossOfControlMask = lossOfControlMask;
1074         this->mClass = class__;
1075         this->mEngine = thisEngine;
1076         const struct iid_vtable *x = class__->mInterfaces;
1077         SLuint8 *interfaceStateP = this->mInterfaceStates;
1078         SLuint32 index;
1079         for (index = 0; index < class__->mInterfaceCount; ++index, ++x, exposedMask >>= 1) {
1080             SLuint8 state;
1081             // initialize all interfaces with init hooks, even if not exposed
1082             const struct MPH_init *mi = &MPH_init_table[x->mMPH];
1083             VoidHook init = mi->mInit;
1084             if (NULL != init) {
1085                 void *self = (char *) this + x->mOffset;
1086                 // IObject does not have an mThis, so [1] is not always defined
1087                 if (index) {
1088                     ((IObject **) self)[1] = this;
1089                 }
1090                 // call the initialization hook
1091                 (*init)(self);
1092                 // IObject does not require a call to GetInterface
1093                 if (index) {
1094                     // This trickery invalidates the v-table until GetInterface
1095                     ((size_t *) self)[0] ^= ~0;
1096                 }
1097                 // if interface is exposed, also call the optional expose hook
1098                 BoolHook expose;
1099                 state = (exposedMask & 1) && ((NULL == (expose = mi->mExpose)) || (*expose)(self)) ?
1100                         INTERFACE_EXPOSED : INTERFACE_INITIALIZED;
1101                 // FIXME log or report to application if an expose hook on a
1102                 // required explicit interface fails at creation time
1103             } else {
1104                 state = INTERFACE_UNINITIALIZED;
1105             }
1106             *interfaceStateP++ = state;
1107         }
1108         // note that the new object is not yet published; creator must call IObject_Publish
1109     }
1110     return this;
1111 }
1112 
1113 
1114 /* This implementation supports at most one engine */
1115 
1116 static CEngine *theOneTrueEngine = NULL;
1117 static pthread_mutex_t theOneTrueMutex = PTHREAD_MUTEX_INITIALIZER;
1118 
1119 
1120 /** \brief Called by dlopen when .so is loaded */
1121 
onDlOpen(void)1122 __attribute__((constructor)) static void onDlOpen(void)
1123 {
1124 }
1125 
1126 
1127 /** \brief Called by dlclose when .so is unloaded */
1128 
onDlClose(void)1129 __attribute__((destructor)) static void onDlClose(void)
1130 {
1131     if (NULL != theOneTrueEngine) {
1132         SL_LOGE("Object::Destroy omitted for engine %p", theOneTrueEngine);
1133     }
1134 }
1135 
1136 /** \brief Called by IObject::Destroy after engine is destroyed. The parameter refers to the
1137  *  previous engine, which is now undefined memory.
1138  */
1139 
CEngine_Destroyed(CEngine * self)1140 void CEngine_Destroyed(CEngine *self)
1141 {
1142     int ok;
1143     ok = pthread_mutex_lock(&theOneTrueMutex);
1144     assert(0 == ok);
1145     assert(self == theOneTrueEngine);
1146     theOneTrueEngine = NULL;
1147     ok = pthread_mutex_unlock(&theOneTrueMutex);
1148     assert(0 == ok);
1149 }
1150 
1151 
1152 /* Initial global entry points */
1153 
1154 
1155 /** \brief slCreateEngine Function */
1156 
slCreateEngine(SLObjectItf * pEngine,SLuint32 numOptions,const SLEngineOption * pEngineOptions,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)1157 SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
1158     const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
1159     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
1160 {
1161     SL_ENTER_GLOBAL
1162 
1163     int ok;
1164     ok = pthread_mutex_lock(&theOneTrueMutex);
1165     assert(0 == ok);
1166 
1167     do {
1168 
1169 #ifdef ANDROID
1170         android::ProcessState::self()->startThreadPool();
1171 #ifndef USE_BACKPORT
1172         android::DataSource::RegisterDefaultSniffers();
1173 #endif
1174 #endif
1175 
1176         if (NULL == pEngine) {
1177             result = SL_RESULT_PARAMETER_INVALID;
1178             break;
1179         }
1180         *pEngine = NULL;
1181 
1182         if (NULL != theOneTrueEngine) {
1183             SL_LOGE("slCreateEngine while another engine %p is active", theOneTrueEngine);
1184             result = SL_RESULT_RESOURCE_ERROR;
1185             break;
1186         }
1187 
1188         if ((0 < numOptions) && (NULL == pEngineOptions)) {
1189             SL_LOGE("numOptions=%lu and pEngineOptions=NULL", numOptions);
1190             result = SL_RESULT_PARAMETER_INVALID;
1191             break;
1192         }
1193 
1194         // default values
1195         SLboolean threadSafe = SL_BOOLEAN_TRUE;
1196         SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE;
1197 
1198         // process engine options
1199         SLuint32 i;
1200         const SLEngineOption *option = pEngineOptions;
1201         result = SL_RESULT_SUCCESS;
1202         for (i = 0; i < numOptions; ++i, ++option) {
1203             switch (option->feature) {
1204             case SL_ENGINEOPTION_THREADSAFE:
1205                 threadSafe = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize
1206                 break;
1207             case SL_ENGINEOPTION_LOSSOFCONTROL:
1208                 lossOfControlGlobal = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize
1209                 break;
1210             default:
1211                 SL_LOGE("unknown engine option: feature=%lu data=%lu",
1212                     option->feature, option->data);
1213                 result = SL_RESULT_PARAMETER_INVALID;
1214                 break;
1215             }
1216         }
1217         if (SL_RESULT_SUCCESS != result) {
1218             break;
1219         }
1220 
1221         unsigned exposedMask;
1222         const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE);
1223         assert(NULL != pCEngine_class);
1224         result = checkInterfaces(pCEngine_class, numInterfaces,
1225             pInterfaceIds, pInterfaceRequired, &exposedMask);
1226         if (SL_RESULT_SUCCESS != result) {
1227             break;
1228         }
1229 
1230         CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL);
1231         if (NULL == this) {
1232             result = SL_RESULT_MEMORY_FAILURE;
1233             break;
1234         }
1235 
1236         // initialize fields not associated with an interface
1237         memset(&this->mSyncThread, 0, sizeof(pthread_t));
1238         // initialize fields related to an interface
1239         this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0;
1240         this->mEngine.mLossOfControlGlobal = lossOfControlGlobal;
1241         this->mEngineCapabilities.mThreadSafe = threadSafe;
1242         IObject_Publish(&this->mObject);
1243         theOneTrueEngine = this;
1244         // return the new engine object
1245         *pEngine = &this->mObject.mItf;
1246 
1247     } while(0);
1248 
1249     ok = pthread_mutex_unlock(&theOneTrueMutex);
1250     assert(0 == ok);
1251 
1252     SL_LEAVE_GLOBAL
1253 }
1254 
1255 
1256 /** \brief slQueryNumSupportedEngineInterfaces Function */
1257 
slQueryNumSupportedEngineInterfaces(SLuint32 * pNumSupportedInterfaces)1258 SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces)
1259 {
1260     SL_ENTER_GLOBAL
1261 
1262     if (NULL == pNumSupportedInterfaces) {
1263         result = SL_RESULT_PARAMETER_INVALID;
1264     } else {
1265         const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE);
1266         assert(NULL != class__);
1267         SLuint32 count = 0;
1268         SLuint32 i;
1269         for (i = 0; i < class__->mInterfaceCount; ++i) {
1270             switch (class__->mInterfaces[i].mInterface) {
1271             case INTERFACE_IMPLICIT:
1272             case INTERFACE_IMPLICIT_PREREALIZE:
1273             case INTERFACE_EXPLICIT:
1274             case INTERFACE_EXPLICIT_PREREALIZE:
1275             case INTERFACE_DYNAMIC:
1276                 ++count;
1277                 break;
1278             case INTERFACE_UNAVAILABLE:
1279                 break;
1280             default:
1281                 assert(false);
1282                 break;
1283             }
1284         }
1285         *pNumSupportedInterfaces = count;
1286         result = SL_RESULT_SUCCESS;
1287     }
1288 
1289     SL_LEAVE_GLOBAL
1290 }
1291 
1292 
1293 /** \brief slQuerySupportedEngineInterfaces Function */
1294 
slQuerySupportedEngineInterfaces(SLuint32 index,SLInterfaceID * pInterfaceId)1295 SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId)
1296 {
1297     SL_ENTER_GLOBAL
1298 
1299     if (NULL == pInterfaceId) {
1300         result = SL_RESULT_PARAMETER_INVALID;
1301     } else {
1302         *pInterfaceId = NULL;
1303         const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE);
1304         assert(NULL != class__);
1305         result = SL_RESULT_PARAMETER_INVALID;   // will be reset later
1306         SLuint32 i;
1307         for (i = 0; i < class__->mInterfaceCount; ++i) {
1308             switch (class__->mInterfaces[i].mInterface) {
1309             case INTERFACE_IMPLICIT:
1310             case INTERFACE_IMPLICIT_PREREALIZE:
1311             case INTERFACE_EXPLICIT:
1312             case INTERFACE_EXPLICIT_PREREALIZE:
1313             case INTERFACE_DYNAMIC:
1314                 break;
1315             case INTERFACE_UNAVAILABLE:
1316                 continue;
1317             default:
1318                 assert(false);
1319                 break;
1320             }
1321             if (index == 0) {
1322                 // The engine has no aliases, but if it did, this would return only the primary
1323                 *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH];
1324                 result = SL_RESULT_SUCCESS;
1325                 break;
1326             }
1327             --index;
1328         }
1329     }
1330 
1331     SL_LEAVE_GLOBAL
1332 }
1333