entry.c revision 527f8ca99f2938d6569fc25dcf3256985a54dec6
18db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/*
28db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * Copyright (C) 2010 The Android Open Source Project
38db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten *
48db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
58db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * you may not use this file except in compliance with the License.
68db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * You may obtain a copy of the License at
78db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten *
88db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
98db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten *
108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * Unless required by applicable law or agreed to in writing, software
118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
128db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * See the License for the specific language governing permissions and
148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten * limitations under the License.
158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten */
168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/* Initial global entry points */
188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#include "sles_allinclusive.h"
208db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** \brief Internal code shared by slCreateEngine and xaCreateEngine */
238db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
24527f8ca99f2938d6569fc25dcf3256985a54dec6Glenn KastenLI_API SLresult liCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired,
278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    const ClassTable *pCEngine_class)
288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{
298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    SLresult result;
308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    int ok;
328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    ok = pthread_mutex_lock(&theOneTrueMutex);
338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    assert(0 == ok);
341d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten    bool needToUnlockTheOneTrueMutex = true;
358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
368db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    do {
378db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
388db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        if (NULL == pEngine) {
398db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
408db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            break;
418db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
428db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        *pEngine = NULL;
438db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
448db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        if ((0 < numOptions) && (NULL == pEngineOptions)) {
458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            SL_LOGE("numOptions=%lu and pEngineOptions=NULL", numOptions);
468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
478db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            break;
488db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
498db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
508db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        // default values
518db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        SLboolean threadSafe = SL_BOOLEAN_TRUE;
528db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE;
538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
548db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        // process engine options
558db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        SLuint32 i;
568db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        const SLEngineOption *option = pEngineOptions;
578db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        result = SL_RESULT_SUCCESS;
588db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        for (i = 0; i < numOptions; ++i, ++option) {
598db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            switch (option->feature) {
608db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case SL_ENGINEOPTION_THREADSAFE:
618db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                threadSafe = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize
628db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
638db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case SL_ENGINEOPTION_LOSSOFCONTROL:
648db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                lossOfControlGlobal = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize
658db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
668db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            default:
678db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                SL_LOGE("unknown engine option: feature=%lu data=%lu",
688db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                    option->feature, option->data);
698db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                result = SL_RESULT_PARAMETER_INVALID;
708db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            }
728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        if (SL_RESULT_SUCCESS != result) {
748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            break;
758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
778db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        unsigned exposedMask;
788db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        assert(NULL != pCEngine_class);
798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        result = checkInterfaces(pCEngine_class, numInterfaces,
808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            pInterfaceIds, pInterfaceRequired, &exposedMask);
818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        if (SL_RESULT_SUCCESS != result) {
828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            break;
838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
848db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
851d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        // if an engine already exists, then increment its ref count
86bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        CEngine *thiz = theOneTrueEngine;
87bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        if (NULL != thiz) {
881d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            assert(0 < theOneTrueRefCount);
891d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            ++theOneTrueRefCount;
901d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten
911d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            // In order to update the engine object, we need to lock it,
921d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            // but that would violate the lock order and potentially deadlock.
931d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            // So we unlock now and note that it should not be unlocked later.
941d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            ok = pthread_mutex_unlock(&theOneTrueMutex);
951d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            assert(0 == ok);
961d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            needToUnlockTheOneTrueMutex = false;
97bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            object_lock_exclusive(&thiz->mObject);
981d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten
991d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            // now expose additional interfaces not requested by the earlier engine create
1001d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            const struct iid_vtable *x = pCEngine_class->mInterfaces;
101bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            SLuint8 *interfaceStateP = thiz->mObject.mInterfaceStates;
1021d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            SLuint32 index;
1031d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            for (index = 0; index < pCEngine_class->mInterfaceCount; ++index, ++x,
1041d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    exposedMask >>= 1, ++interfaceStateP) {
1051d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                switch (*interfaceStateP) {
1061d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                case INTERFACE_EXPOSED:         // previously exposed
1071d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    break;
1081d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                case INTERFACE_INITIALIZED:     // not exposed during the earlier create
1091d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    if (exposedMask & 1) {
1101d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                        const struct MPH_init *mi = &MPH_init_table[x->mMPH];
1111d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                        BoolHook expose = mi->mExpose;
112bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                        if ((NULL == expose) || (*expose)((char *) thiz + x->mOffset)) {
1131d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                            *interfaceStateP = INTERFACE_EXPOSED;
1141d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                        }
1151d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                        // FIXME log or report to application that expose hook failed
1161d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    }
1171d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    break;
1181d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                case INTERFACE_UNINITIALIZED:   // no init hook
1191d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    break;
1201d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                default:                        // impossible
1211d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    assert(false);
1221d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                    break;
1231d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten                }
1241d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            }
125bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            object_unlock_exclusive(&thiz->mObject);
1261d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            // return the shared engine object
127bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            *pEngine = &thiz->mObject.mItf;
1281d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten            break;
1291d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        }
1301d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten
1311d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        // here when creating the first engine reference
1321d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        assert(0 == theOneTrueRefCount);
1331d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten
1341d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten#ifdef ANDROID
1351d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        android::ProcessState::self()->startThreadPool();
1361d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        android::DataSource::RegisterDefaultSniffers();
1371d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten#endif
1381d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten
139bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz = (CEngine *) construct(pCEngine_class, exposedMask, NULL);
140bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        if (NULL == thiz) {
1418db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            result = SL_RESULT_MEMORY_FAILURE;
1428db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            break;
1438db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
1448db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
1458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        // initialize fields not associated with an interface
1468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        // mThreadPool is initialized in CEngine_Realize
147bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        memset(&thiz->mThreadPool, 0, sizeof(ThreadPool));
148bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        memset(&thiz->mSyncThread, 0, sizeof(pthread_t));
149faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if defined(ANDROID)
150bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mEqNumPresets = 0;
151bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mEqPresetNames = NULL;
1528db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten#endif
1538db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        // initialize fields related to an interface
154bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0;
155bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mEngine.mLossOfControlGlobal = lossOfControlGlobal;
156bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mEngineCapabilities.mThreadSafe = threadSafe;
157bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        IObject_Publish(&thiz->mObject);
158bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        theOneTrueEngine = thiz;
1591d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        theOneTrueRefCount = 1;
1608db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        // return the new engine object
161bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        *pEngine = &thiz->mObject.mItf;
1628db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
1638db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    } while(0);
1648db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
1651d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten    if (needToUnlockTheOneTrueMutex) {
1661d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        ok = pthread_mutex_unlock(&theOneTrueMutex);
1671d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        assert(0 == ok);
1681d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten        needToUnlockTheOneTrueMutex = false;
1691d081e49a10543018e1ae33792bd3d30504719baGlenn Kasten    }
1708db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
1718db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    return result;
1728db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten}
1738db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
1748db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
1758db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** Internal function for slQuerySupportedEngineInterfaces and xaQuerySupportedEngineInterfaces */
1768db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
177527f8ca99f2938d6569fc25dcf3256985a54dec6Glenn KastenLI_API SLresult liQueryNumSupportedInterfaces(SLuint32 *pNumSupportedInterfaces,
178bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        const ClassTable *clazz)
1798db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{
1808db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    SLresult result;
1818db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    if (NULL == pNumSupportedInterfaces) {
1828db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
1838db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    } else {
184bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        assert(NULL != clazz);
1858db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        SLuint32 count = 0;
1868db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        SLuint32 i;
187bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        for (i = 0; i < clazz->mInterfaceCount; ++i) {
188bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            switch (clazz->mInterfaces[i].mInterface) {
1898db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_IMPLICIT:
1908db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_IMPLICIT_PREREALIZE:
1918db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_EXPLICIT:
1928db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_EXPLICIT_PREREALIZE:
1938db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_DYNAMIC:
1948db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                ++count;
1958db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
1968db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_UNAVAILABLE:
1978db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
1988db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            default:
1998db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                assert(false);
2008db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
2018db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            }
2028db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
2038db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        *pNumSupportedInterfaces = count;
2048db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        result = SL_RESULT_SUCCESS;
2058db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    }
2068db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    return result;
2078db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten}
2088db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
2098db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
2108db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten/** Internal function for slQuerySupportedEngineInterfaces and xaQuerySupportedEngineInterfaces */
2118db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten
212527f8ca99f2938d6569fc25dcf3256985a54dec6Glenn KastenLI_API SLresult liQuerySupportedInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId,
213bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        const ClassTable *clazz)
2148db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten{
2158db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    SLresult result;
2168db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    if (NULL == pInterfaceId) {
2178db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
2188db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    } else {
2198db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        *pInterfaceId = NULL;
220bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        assert(NULL != clazz);
2218db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        result = SL_RESULT_PARAMETER_INVALID;   // will be reset later
2228db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        SLuint32 i;
223bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        for (i = 0; i < clazz->mInterfaceCount; ++i) {
224bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            switch (clazz->mInterfaces[i].mInterface) {
2258db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_IMPLICIT:
2268db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_IMPLICIT_PREREALIZE:
2278db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_EXPLICIT:
2288db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_EXPLICIT_PREREALIZE:
2298db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_DYNAMIC:
2308db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
2318db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            case INTERFACE_UNAVAILABLE:
2328db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                continue;
2338db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            default:
2348db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                assert(false);
2358db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
2368db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            }
2378db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            if (index == 0) {
238bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten                *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH];
2398db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                result = SL_RESULT_SUCCESS;
2408db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten                break;
2418db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            }
2428db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten            --index;
2438db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten        }
2448db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    }
2458db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten    return result;
2468db0b106cdce5f5216b1535492de7930ad738aedGlenn Kasten}
247