10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/*
20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * you may not use this file except in compliance with the License.
60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * You may obtain a copy of the License at
70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Unless required by applicable law or agreed to in writing, software
110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * See the License for the specific language governing permissions and
140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * limitations under the License.
150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten */
160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* EngineCapabilities implementation */
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#include "sles_allinclusive.h"
200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
220b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngineCapabilities_QuerySupportedProfiles(
230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLEngineCapabilitiesItf self, SLuint16 *pProfilesSupported)
240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
26ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
27ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pProfilesSupported) {
28ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
29ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
30a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten        // The generic implementation doesn't implement any of the profiles, they shouldn't be
31a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten        // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
32a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten        *pProfilesSupported = USE_PROFILES &
33a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten                (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
34ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
35ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
36ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
37ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
40ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
41a438eb1cf1ae602afab00336528dd230bd929206Glenn Kastenstatic SLresult IEngineCapabilities_QueryAvailableVoices(SLEngineCapabilitiesItf self,
42a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten    SLuint16 voiceType, SLint16 *pNumMaxVoices, SLboolean *pIsAbsoluteMax, SLint16 *pNumFreeVoices)
430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
44ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
45ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    switch (voiceType) {
470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_VOICETYPE_2D_AUDIO:
480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_VOICETYPE_MIDI:
490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_VOICETYPE_3D_AUDIO:
500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_VOICETYPE_3D_MIDIOUTPUT:
51ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pNumMaxVoices)
52a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten            *pNumMaxVoices = MAX_INSTANCE - 2;
53ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pIsAbsoluteMax)
54ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pIsAbsoluteMax = SL_BOOLEAN_TRUE;
55ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pNumFreeVoices)
56a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten            *pNumFreeVoices = MAX_INSTANCE - 2;
57ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        break;
590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    default:
60ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
61ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        break;
620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
63ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
64ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
67ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
680b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngineCapabilities_QueryNumberOfMIDISynthesizers(
690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLEngineCapabilitiesItf self, SLint16 *pNum)
700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
71ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
72ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
73ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNum) {
74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
75ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
76ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNum = 1;
77ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
79ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
80ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
83ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
840b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngineCapabilities_QueryAPIVersion(SLEngineCapabilitiesItf self,
850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLint16 *pMajor, SLint16 *pMinor, SLint16 *pStep)
860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
87ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
88ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
89ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!(NULL != pMajor && NULL != pMinor && NULL != pStep)) {
90ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
91ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
92ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pMajor = 1;
93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pMinor = 0;
94ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pStep = 1;
95ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
96ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
97ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
98ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
102b0ab2dee391dd2cb257faeaba252ee6ecccc5f03Glenn KastenSLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
103d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor)
1040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
105ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
107bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IEngineCapabilities *thiz = (IEngineCapabilities *) self;
10840d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten    const struct LED_id_descriptor *id_descriptor;
1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 index;
1100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL != pIndex) {
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
1120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        if (NULL != pLEDDeviceID || NULL != pDescriptor) {
1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten            index = *pIndex;
114bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            if (index >= thiz->mMaxIndexLED) {
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                result = SL_RESULT_PARAMETER_INVALID;
116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            } else {
117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                id_descriptor = &LED_id_descriptors[index];
118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                if (NULL != pLEDDeviceID)
119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    *pLEDDeviceID = id_descriptor->id;
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                if (NULL != pDescriptor)
121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    *pDescriptor = *id_descriptor->descriptor;
122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            }
1230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        }
124bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        *pIndex = thiz->mMaxIndexLED;
1250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    } else {
126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
1270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        if (NULL != pLEDDeviceID && NULL != pDescriptor) {
1280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten            SLuint32 id = *pLEDDeviceID;
129bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            for (index = 0; index < thiz->mMaxIndexLED; ++index) {
1300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                id_descriptor = &LED_id_descriptors[index];
1310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                if (id == id_descriptor->id) {
1320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                    *pDescriptor = *id_descriptor->descriptor;
133ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    result = SL_RESULT_SUCCESS;
134ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    break;
1350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                }
1360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten            }
1370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        }
1380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
1410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
143ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
144b0ab2dee391dd2cb257faeaba252ee6ecccc5f03Glenn KastenSLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
145d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor)
1460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
149bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IEngineCapabilities *thiz = (IEngineCapabilities *) self;
15040d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten    const struct Vibra_id_descriptor *id_descriptor;
1510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 index;
1520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL != pIndex) {
153ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
1540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        if (NULL != pVibraDeviceID || NULL != pDescriptor) {
1550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten            index = *pIndex;
156bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            if (index >= thiz->mMaxIndexVibra) {
157ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                result = SL_RESULT_PARAMETER_INVALID;
158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            } else {
159ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                id_descriptor = &Vibra_id_descriptors[index];
160ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                if (NULL != pVibraDeviceID)
161ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    *pVibraDeviceID = id_descriptor->id;
162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                if (NULL != pDescriptor)
163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    *pDescriptor = *id_descriptor->descriptor;
164ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            }
1650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        }
166bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        *pIndex = thiz->mMaxIndexVibra;
1670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    } else {
168ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
1690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        if (NULL != pVibraDeviceID && NULL != pDescriptor) {
1700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten            SLuint32 id = *pVibraDeviceID;
171bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten            for (index = 0; index < thiz->mMaxIndexVibra; ++index) {
1720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                id_descriptor = &Vibra_id_descriptors[index];
1730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                if (id == id_descriptor->id) {
1740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                    *pDescriptor = *id_descriptor->descriptor;
175ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    result = SL_RESULT_SUCCESS;
176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                    break;
1770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten                }
1780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten            }
1790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        }
1800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
1830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1860b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IEngineCapabilities_IsThreadSafe(SLEngineCapabilitiesItf self,
1870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLboolean *pIsThreadSafe)
1880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
189ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
190ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pIsThreadSafe) {
192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
193ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
194bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        IEngineCapabilities *thiz = (IEngineCapabilities *) self;
195bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        *pIsThreadSafe = thiz->mThreadSafe;
196ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
198ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
199ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
2000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
2010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
202ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2030b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLEngineCapabilitiesItf_ IEngineCapabilities_Itf = {
2040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_QuerySupportedProfiles,
2050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_QueryAvailableVoices,
2060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_QueryNumberOfMIDISynthesizers,
2070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_QueryAPIVersion,
2080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_QueryLEDCapabilities,
2090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_QueryVibraCapabilities,
2100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IEngineCapabilities_IsThreadSafe
2110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
2120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
2130b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IEngineCapabilities_init(void *self)
2140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
215bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    IEngineCapabilities *thiz = (IEngineCapabilities *) self;
216bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mItf = &IEngineCapabilities_Itf;
2170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // mThreadSafe is initialized in slCreateEngine
21840d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten    const struct LED_id_descriptor *id_descriptor_LED = LED_id_descriptors;
21940d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten    while (NULL != id_descriptor_LED->descriptor)
22040d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten        ++id_descriptor_LED;
221bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mMaxIndexLED = id_descriptor_LED - LED_id_descriptors;
22240d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten    const struct Vibra_id_descriptor *id_descriptor_Vibra = Vibra_id_descriptors;
22340d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten    while (NULL != id_descriptor_Vibra->descriptor)
22440d1c40832a448e23d0bb37512aee53222575c2eGlenn Kasten        ++id_descriptor_Vibra;
225bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mMaxIndexVibra = id_descriptor_Vibra - Vibra_id_descriptors;
2260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
227