1*bebae9c0SAndroid Build Coastguard Worker /*
2*bebae9c0SAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*bebae9c0SAndroid Build Coastguard Worker *
4*bebae9c0SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*bebae9c0SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*bebae9c0SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*bebae9c0SAndroid Build Coastguard Worker *
8*bebae9c0SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*bebae9c0SAndroid Build Coastguard Worker *
10*bebae9c0SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*bebae9c0SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*bebae9c0SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*bebae9c0SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*bebae9c0SAndroid Build Coastguard Worker * limitations under the License.
15*bebae9c0SAndroid Build Coastguard Worker */
16*bebae9c0SAndroid Build Coastguard Worker
17*bebae9c0SAndroid Build Coastguard Worker /* 3DGrouping implementation */
18*bebae9c0SAndroid Build Coastguard Worker
19*bebae9c0SAndroid Build Coastguard Worker #include "sles_allinclusive.h"
20*bebae9c0SAndroid Build Coastguard Worker
21*bebae9c0SAndroid Build Coastguard Worker
I3DGrouping_Set3DGroup(SL3DGroupingItf self,SLObjectItf group)22*bebae9c0SAndroid Build Coastguard Worker static SLresult I3DGrouping_Set3DGroup(SL3DGroupingItf self, SLObjectItf group)
23*bebae9c0SAndroid Build Coastguard Worker {
24*bebae9c0SAndroid Build Coastguard Worker SL_ENTER_INTERFACE
25*bebae9c0SAndroid Build Coastguard Worker
26*bebae9c0SAndroid Build Coastguard Worker // validate input parameters
27*bebae9c0SAndroid Build Coastguard Worker C3DGroup *newGroup = (C3DGroup *) group;
28*bebae9c0SAndroid Build Coastguard Worker result = SL_RESULT_SUCCESS;
29*bebae9c0SAndroid Build Coastguard Worker if (NULL != newGroup) {
30*bebae9c0SAndroid Build Coastguard Worker // check that new group has the correct object ID and is realized, and acquire a strong
31*bebae9c0SAndroid Build Coastguard Worker // reference to it. FYI note that a deadlock will occur if application incorrectly
32*bebae9c0SAndroid Build Coastguard Worker // specifies group as this audio player
33*bebae9c0SAndroid Build Coastguard Worker result = AcquireStrongRef(&newGroup->mObject, SL_OBJECTID_3DGROUP);
34*bebae9c0SAndroid Build Coastguard Worker // the new group is left unlocked, but it will be locked again below
35*bebae9c0SAndroid Build Coastguard Worker }
36*bebae9c0SAndroid Build Coastguard Worker if (SL_RESULT_SUCCESS == result) {
37*bebae9c0SAndroid Build Coastguard Worker I3DGrouping *thiz = (I3DGrouping *) self;
38*bebae9c0SAndroid Build Coastguard Worker IObject *thisObject = InterfaceToIObject(thiz);
39*bebae9c0SAndroid Build Coastguard Worker unsigned id = thisObject->mInstanceID;
40*bebae9c0SAndroid Build Coastguard Worker assert(0 != id); // player object must be published by this point
41*bebae9c0SAndroid Build Coastguard Worker --id;
42*bebae9c0SAndroid Build Coastguard Worker assert(MAX_INSTANCE > id);
43*bebae9c0SAndroid Build Coastguard Worker unsigned mask = 1 << id;
44*bebae9c0SAndroid Build Coastguard Worker interface_lock_exclusive(thiz);
45*bebae9c0SAndroid Build Coastguard Worker C3DGroup *oldGroup = thiz->mGroup;
46*bebae9c0SAndroid Build Coastguard Worker if (newGroup != oldGroup) {
47*bebae9c0SAndroid Build Coastguard Worker // remove this object from the old group's set of objects
48*bebae9c0SAndroid Build Coastguard Worker if (NULL != oldGroup) {
49*bebae9c0SAndroid Build Coastguard Worker IObject *oldGroupObject = &oldGroup->mObject;
50*bebae9c0SAndroid Build Coastguard Worker // note that we already have a strong reference to the old group
51*bebae9c0SAndroid Build Coastguard Worker object_lock_exclusive(oldGroupObject);
52*bebae9c0SAndroid Build Coastguard Worker assert(oldGroup->mMemberMask & mask);
53*bebae9c0SAndroid Build Coastguard Worker oldGroup->mMemberMask &= ~mask;
54*bebae9c0SAndroid Build Coastguard Worker ReleaseStrongRefAndUnlockExclusive(oldGroupObject);
55*bebae9c0SAndroid Build Coastguard Worker }
56*bebae9c0SAndroid Build Coastguard Worker // add this object to the new group's set of objects
57*bebae9c0SAndroid Build Coastguard Worker if (NULL != newGroup) {
58*bebae9c0SAndroid Build Coastguard Worker IObject *newGroupObject = &newGroup->mObject;
59*bebae9c0SAndroid Build Coastguard Worker // we already have a strong reference to the new group, but we need to re-lock it
60*bebae9c0SAndroid Build Coastguard Worker // so that we always lock objects in the same nesting order to prevent a deadlock
61*bebae9c0SAndroid Build Coastguard Worker object_lock_exclusive(newGroupObject);
62*bebae9c0SAndroid Build Coastguard Worker assert(!(newGroup->mMemberMask & mask));
63*bebae9c0SAndroid Build Coastguard Worker newGroup->mMemberMask |= mask;
64*bebae9c0SAndroid Build Coastguard Worker object_unlock_exclusive(newGroupObject);
65*bebae9c0SAndroid Build Coastguard Worker }
66*bebae9c0SAndroid Build Coastguard Worker thiz->mGroup = newGroup;
67*bebae9c0SAndroid Build Coastguard Worker }
68*bebae9c0SAndroid Build Coastguard Worker interface_unlock_exclusive(thiz);
69*bebae9c0SAndroid Build Coastguard Worker }
70*bebae9c0SAndroid Build Coastguard Worker
71*bebae9c0SAndroid Build Coastguard Worker SL_LEAVE_INTERFACE
72*bebae9c0SAndroid Build Coastguard Worker }
73*bebae9c0SAndroid Build Coastguard Worker
74*bebae9c0SAndroid Build Coastguard Worker
I3DGrouping_Get3DGroup(SL3DGroupingItf self,SLObjectItf * pGroup)75*bebae9c0SAndroid Build Coastguard Worker static SLresult I3DGrouping_Get3DGroup(SL3DGroupingItf self, SLObjectItf *pGroup)
76*bebae9c0SAndroid Build Coastguard Worker {
77*bebae9c0SAndroid Build Coastguard Worker SL_ENTER_INTERFACE
78*bebae9c0SAndroid Build Coastguard Worker
79*bebae9c0SAndroid Build Coastguard Worker if (NULL == pGroup) {
80*bebae9c0SAndroid Build Coastguard Worker result = SL_RESULT_PARAMETER_INVALID;
81*bebae9c0SAndroid Build Coastguard Worker } else {
82*bebae9c0SAndroid Build Coastguard Worker I3DGrouping *thiz = (I3DGrouping *) self;
83*bebae9c0SAndroid Build Coastguard Worker interface_lock_shared(thiz);
84*bebae9c0SAndroid Build Coastguard Worker C3DGroup *group = thiz->mGroup;
85*bebae9c0SAndroid Build Coastguard Worker *pGroup = (NULL != group) ? &group->mObject.mItf : NULL;
86*bebae9c0SAndroid Build Coastguard Worker interface_unlock_shared(thiz);
87*bebae9c0SAndroid Build Coastguard Worker result = SL_RESULT_SUCCESS;
88*bebae9c0SAndroid Build Coastguard Worker }
89*bebae9c0SAndroid Build Coastguard Worker
90*bebae9c0SAndroid Build Coastguard Worker SL_LEAVE_INTERFACE
91*bebae9c0SAndroid Build Coastguard Worker }
92*bebae9c0SAndroid Build Coastguard Worker
93*bebae9c0SAndroid Build Coastguard Worker
94*bebae9c0SAndroid Build Coastguard Worker static const struct SL3DGroupingItf_ I3DGrouping_Itf = {
95*bebae9c0SAndroid Build Coastguard Worker I3DGrouping_Set3DGroup,
96*bebae9c0SAndroid Build Coastguard Worker I3DGrouping_Get3DGroup
97*bebae9c0SAndroid Build Coastguard Worker };
98*bebae9c0SAndroid Build Coastguard Worker
I3DGrouping_init(void * self)99*bebae9c0SAndroid Build Coastguard Worker void I3DGrouping_init(void *self)
100*bebae9c0SAndroid Build Coastguard Worker {
101*bebae9c0SAndroid Build Coastguard Worker I3DGrouping *thiz = (I3DGrouping *) self;
102*bebae9c0SAndroid Build Coastguard Worker thiz->mItf = &I3DGrouping_Itf;
103*bebae9c0SAndroid Build Coastguard Worker thiz->mGroup = NULL;
104*bebae9c0SAndroid Build Coastguard Worker }
105*bebae9c0SAndroid Build Coastguard Worker
I3DGrouping_deinit(void * self)106*bebae9c0SAndroid Build Coastguard Worker void I3DGrouping_deinit(void *self)
107*bebae9c0SAndroid Build Coastguard Worker {
108*bebae9c0SAndroid Build Coastguard Worker I3DGrouping *thiz = (I3DGrouping *) self;
109*bebae9c0SAndroid Build Coastguard Worker C3DGroup *group = thiz->mGroup;
110*bebae9c0SAndroid Build Coastguard Worker if (NULL != group) {
111*bebae9c0SAndroid Build Coastguard Worker unsigned mask = 1 << (InterfaceToIObject(thiz)->mInstanceID - 1);
112*bebae9c0SAndroid Build Coastguard Worker IObject *groupObject = &group->mObject;
113*bebae9c0SAndroid Build Coastguard Worker object_lock_exclusive(groupObject);
114*bebae9c0SAndroid Build Coastguard Worker assert(group->mMemberMask & mask);
115*bebae9c0SAndroid Build Coastguard Worker group->mMemberMask &= ~mask;
116*bebae9c0SAndroid Build Coastguard Worker ReleaseStrongRefAndUnlockExclusive(groupObject);
117*bebae9c0SAndroid Build Coastguard Worker }
118*bebae9c0SAndroid Build Coastguard Worker }
119