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/* PrefetchStatus implementation */
18
19#include "sles_allinclusive.h"
20
21
22static SLresult IPrefetchStatus_GetPrefetchStatus(SLPrefetchStatusItf self, SLuint32 *pStatus)
23{
24    SL_ENTER_INTERFACE
25
26    if (NULL == pStatus) {
27        result = SL_RESULT_PARAMETER_INVALID;
28    } else {
29        IPrefetchStatus *thiz = (IPrefetchStatus *) self;
30        interface_lock_shared(thiz);
31        SLuint32 status = thiz->mStatus;
32        interface_unlock_shared(thiz);
33        *pStatus = status;
34        result = SL_RESULT_SUCCESS;
35    }
36
37    SL_LEAVE_INTERFACE
38}
39
40
41static SLresult IPrefetchStatus_GetFillLevel(SLPrefetchStatusItf self, SLpermille *pLevel)
42{
43    SL_ENTER_INTERFACE
44
45    if (NULL == pLevel) {
46        result = SL_RESULT_PARAMETER_INVALID;
47    } else {
48        IPrefetchStatus *thiz = (IPrefetchStatus *) self;
49        interface_lock_shared(thiz);
50        SLpermille level = thiz->mLevel;
51        interface_unlock_shared(thiz);
52        *pLevel = level;
53        result = SL_RESULT_SUCCESS;
54    }
55
56    SL_LEAVE_INTERFACE
57}
58
59
60static SLresult IPrefetchStatus_RegisterCallback(SLPrefetchStatusItf self,
61    slPrefetchCallback callback, void *pContext)
62{
63    SL_ENTER_INTERFACE
64
65    IPrefetchStatus *thiz = (IPrefetchStatus *) self;
66    interface_lock_exclusive(thiz);
67    thiz->mCallback = callback;
68    thiz->mContext = pContext;
69    interface_unlock_exclusive(thiz);
70    result = SL_RESULT_SUCCESS;
71
72    SL_LEAVE_INTERFACE
73}
74
75
76static SLresult IPrefetchStatus_SetCallbackEventsMask(SLPrefetchStatusItf self, SLuint32 eventFlags)
77{
78    SL_ENTER_INTERFACE
79
80    if (eventFlags & ~(SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)) {
81        result = SL_RESULT_PARAMETER_INVALID;
82
83    } else {
84        IPrefetchStatus *thiz = (IPrefetchStatus *) self;
85        interface_lock_exclusive(thiz);
86        thiz->mCallbackEventsMask = eventFlags;
87        interface_unlock_exclusive(thiz);
88        result = SL_RESULT_SUCCESS;
89
90    }
91
92    SL_LEAVE_INTERFACE
93}
94
95
96static SLresult IPrefetchStatus_GetCallbackEventsMask(SLPrefetchStatusItf self,
97    SLuint32 *pEventFlags)
98{
99    SL_ENTER_INTERFACE
100
101    if (NULL == pEventFlags) {
102        result = SL_RESULT_PARAMETER_INVALID;
103    } else {
104        IPrefetchStatus *thiz = (IPrefetchStatus *) self;
105        interface_lock_shared(thiz);
106        SLuint32 callbackEventsMask = thiz->mCallbackEventsMask;
107        interface_unlock_shared(thiz);
108        *pEventFlags = callbackEventsMask;
109        result = SL_RESULT_SUCCESS;
110    }
111
112    SL_LEAVE_INTERFACE
113}
114
115
116static SLresult IPrefetchStatus_SetFillUpdatePeriod(SLPrefetchStatusItf self, SLpermille period)
117{
118    SL_ENTER_INTERFACE
119
120    if (0 == period) {
121        result = SL_RESULT_PARAMETER_INVALID;
122    } else {
123        IPrefetchStatus *thiz = (IPrefetchStatus *) self;
124        interface_lock_exclusive(thiz);
125        thiz->mFillUpdatePeriod = period;
126#ifdef ANDROID
127        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
128            CAudioPlayer *ap = (CAudioPlayer *) thiz->mThis;
129            android_audioPlayer_setBufferingUpdateThresholdPerMille(ap, period);
130        }
131#endif
132        interface_unlock_exclusive(thiz);
133        result = SL_RESULT_SUCCESS;
134    }
135
136    SL_LEAVE_INTERFACE
137}
138
139
140static SLresult IPrefetchStatus_GetFillUpdatePeriod(SLPrefetchStatusItf self, SLpermille *pPeriod)
141{
142    SL_ENTER_INTERFACE
143
144    if (NULL == pPeriod) {
145        result = SL_RESULT_PARAMETER_INVALID;
146    } else {
147        IPrefetchStatus *thiz = (IPrefetchStatus *) self;
148        interface_lock_shared(thiz);
149        SLpermille fillUpdatePeriod = thiz->mFillUpdatePeriod;
150        interface_unlock_shared(thiz);
151        *pPeriod = fillUpdatePeriod;
152        result = SL_RESULT_SUCCESS;
153    }
154
155    SL_LEAVE_INTERFACE
156}
157
158
159static const struct SLPrefetchStatusItf_ IPrefetchStatus_Itf = {
160    IPrefetchStatus_GetPrefetchStatus,
161    IPrefetchStatus_GetFillLevel,
162    IPrefetchStatus_RegisterCallback,
163    IPrefetchStatus_SetCallbackEventsMask,
164    IPrefetchStatus_GetCallbackEventsMask,
165    IPrefetchStatus_SetFillUpdatePeriod,
166    IPrefetchStatus_GetFillUpdatePeriod
167};
168
169void IPrefetchStatus_init(void *self)
170{
171    IPrefetchStatus *thiz = (IPrefetchStatus *) self;
172    thiz->mItf = &IPrefetchStatus_Itf;
173    thiz->mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
174    thiz->mLevel = 0;
175    thiz->mCallback = NULL;
176    thiz->mContext = NULL;
177    thiz->mCallbackEventsMask = 0;
178    thiz->mFillUpdatePeriod = 100;
179#ifdef ANDROID
180    thiz->mDeferredPrefetchCallback = NULL;
181    thiz->mDeferredPrefetchContext  = NULL;
182    thiz->mDeferredPrefetchEvents   = SL_PREFETCHEVENT_NONE;
183#endif
184}
185