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/* EngineCapabilities implementation */
18
19#include "sles_allinclusive.h"
20
21
22static SLresult IEngineCapabilities_QuerySupportedProfiles(
23    SLEngineCapabilitiesItf self, SLuint16 *pProfilesSupported)
24{
25    SL_ENTER_INTERFACE
26
27    if (NULL == pProfilesSupported) {
28        result = SL_RESULT_PARAMETER_INVALID;
29    } else {
30        // The generic implementation doesn't implement any of the profiles, they shouldn't be
31        // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
32        *pProfilesSupported = USE_PROFILES &
33                (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
34        result = SL_RESULT_SUCCESS;
35    }
36
37    SL_LEAVE_INTERFACE
38}
39
40
41static SLresult IEngineCapabilities_QueryAvailableVoices(SLEngineCapabilitiesItf self,
42    SLuint16 voiceType, SLint16 *pNumMaxVoices, SLboolean *pIsAbsoluteMax, SLint16 *pNumFreeVoices)
43{
44    SL_ENTER_INTERFACE
45
46    switch (voiceType) {
47    case SL_VOICETYPE_2D_AUDIO:
48    case SL_VOICETYPE_MIDI:
49    case SL_VOICETYPE_3D_AUDIO:
50    case SL_VOICETYPE_3D_MIDIOUTPUT:
51        if (NULL != pNumMaxVoices)
52            *pNumMaxVoices = MAX_INSTANCE - 2;
53        if (NULL != pIsAbsoluteMax)
54            *pIsAbsoluteMax = SL_BOOLEAN_TRUE;
55        if (NULL != pNumFreeVoices)
56            *pNumFreeVoices = MAX_INSTANCE - 2;
57        result = SL_RESULT_SUCCESS;
58        break;
59    default:
60        result = SL_RESULT_PARAMETER_INVALID;
61        break;
62    }
63
64    SL_LEAVE_INTERFACE
65}
66
67
68static SLresult IEngineCapabilities_QueryNumberOfMIDISynthesizers(
69    SLEngineCapabilitiesItf self, SLint16 *pNum)
70{
71    SL_ENTER_INTERFACE
72
73    if (NULL == pNum) {
74        result = SL_RESULT_PARAMETER_INVALID;
75    } else {
76        *pNum = 1;
77        result = SL_RESULT_SUCCESS;
78    }
79
80    SL_LEAVE_INTERFACE
81}
82
83
84static SLresult IEngineCapabilities_QueryAPIVersion(SLEngineCapabilitiesItf self,
85    SLint16 *pMajor, SLint16 *pMinor, SLint16 *pStep)
86{
87    SL_ENTER_INTERFACE
88
89    if (!(NULL != pMajor && NULL != pMinor && NULL != pStep)) {
90        result = SL_RESULT_PARAMETER_INVALID;
91    } else {
92        *pMajor = 1;
93        *pMinor = 0;
94        *pStep = 1;
95        result = SL_RESULT_SUCCESS;
96    }
97
98    SL_LEAVE_INTERFACE
99}
100
101
102SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
103    SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor)
104{
105    SL_ENTER_INTERFACE
106
107    IEngineCapabilities *thiz = (IEngineCapabilities *) self;
108    const struct LED_id_descriptor *id_descriptor;
109    SLuint32 index;
110    if (NULL != pIndex) {
111        result = SL_RESULT_SUCCESS;
112        if (NULL != pLEDDeviceID || NULL != pDescriptor) {
113            index = *pIndex;
114            if (index >= thiz->mMaxIndexLED) {
115                result = SL_RESULT_PARAMETER_INVALID;
116            } else {
117                id_descriptor = &LED_id_descriptors[index];
118                if (NULL != pLEDDeviceID)
119                    *pLEDDeviceID = id_descriptor->id;
120                if (NULL != pDescriptor)
121                    *pDescriptor = *id_descriptor->descriptor;
122            }
123        }
124        *pIndex = thiz->mMaxIndexLED;
125    } else {
126        result = SL_RESULT_PARAMETER_INVALID;
127        if (NULL != pLEDDeviceID && NULL != pDescriptor) {
128            SLuint32 id = *pLEDDeviceID;
129            for (index = 0; index < thiz->mMaxIndexLED; ++index) {
130                id_descriptor = &LED_id_descriptors[index];
131                if (id == id_descriptor->id) {
132                    *pDescriptor = *id_descriptor->descriptor;
133                    result = SL_RESULT_SUCCESS;
134                    break;
135                }
136            }
137        }
138    }
139
140    SL_LEAVE_INTERFACE
141}
142
143
144SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
145    SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor)
146{
147    SL_ENTER_INTERFACE
148
149    IEngineCapabilities *thiz = (IEngineCapabilities *) self;
150    const struct Vibra_id_descriptor *id_descriptor;
151    SLuint32 index;
152    if (NULL != pIndex) {
153        result = SL_RESULT_SUCCESS;
154        if (NULL != pVibraDeviceID || NULL != pDescriptor) {
155            index = *pIndex;
156            if (index >= thiz->mMaxIndexVibra) {
157                result = SL_RESULT_PARAMETER_INVALID;
158            } else {
159                id_descriptor = &Vibra_id_descriptors[index];
160                if (NULL != pVibraDeviceID)
161                    *pVibraDeviceID = id_descriptor->id;
162                if (NULL != pDescriptor)
163                    *pDescriptor = *id_descriptor->descriptor;
164            }
165        }
166        *pIndex = thiz->mMaxIndexVibra;
167    } else {
168        result = SL_RESULT_PARAMETER_INVALID;
169        if (NULL != pVibraDeviceID && NULL != pDescriptor) {
170            SLuint32 id = *pVibraDeviceID;
171            for (index = 0; index < thiz->mMaxIndexVibra; ++index) {
172                id_descriptor = &Vibra_id_descriptors[index];
173                if (id == id_descriptor->id) {
174                    *pDescriptor = *id_descriptor->descriptor;
175                    result = SL_RESULT_SUCCESS;
176                    break;
177                }
178            }
179        }
180    }
181
182    SL_LEAVE_INTERFACE
183}
184
185
186static SLresult IEngineCapabilities_IsThreadSafe(SLEngineCapabilitiesItf self,
187    SLboolean *pIsThreadSafe)
188{
189    SL_ENTER_INTERFACE
190
191    if (NULL == pIsThreadSafe) {
192        result = SL_RESULT_PARAMETER_INVALID;
193    } else {
194        IEngineCapabilities *thiz = (IEngineCapabilities *) self;
195        *pIsThreadSafe = thiz->mThreadSafe;
196        result = SL_RESULT_SUCCESS;
197    }
198
199    SL_LEAVE_INTERFACE
200}
201
202
203static const struct SLEngineCapabilitiesItf_ IEngineCapabilities_Itf = {
204    IEngineCapabilities_QuerySupportedProfiles,
205    IEngineCapabilities_QueryAvailableVoices,
206    IEngineCapabilities_QueryNumberOfMIDISynthesizers,
207    IEngineCapabilities_QueryAPIVersion,
208    IEngineCapabilities_QueryLEDCapabilities,
209    IEngineCapabilities_QueryVibraCapabilities,
210    IEngineCapabilities_IsThreadSafe
211};
212
213void IEngineCapabilities_init(void *self)
214{
215    IEngineCapabilities *thiz = (IEngineCapabilities *) self;
216    thiz->mItf = &IEngineCapabilities_Itf;
217    // mThreadSafe is initialized in slCreateEngine
218    const struct LED_id_descriptor *id_descriptor_LED = LED_id_descriptors;
219    while (NULL != id_descriptor_LED->descriptor)
220        ++id_descriptor_LED;
221    thiz->mMaxIndexLED = id_descriptor_LED - LED_id_descriptors;
222    const struct Vibra_id_descriptor *id_descriptor_Vibra = Vibra_id_descriptors;
223    while (NULL != id_descriptor_Vibra->descriptor)
224        ++id_descriptor_Vibra;
225    thiz->mMaxIndexVibra = id_descriptor_Vibra - Vibra_id_descriptors;
226}
227