Tizen 2.0 Release
[framework/osp/media.git] / src / FMedia_AudioSessionManagerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 #include <iostream>
18 #include <pthread.h>
19 #include <FBaseSysLog.h>
20 #include <FMediaIAudioSessionEventListener.h>
21 #include "FMedia_AudioSessionManagerImpl.h"
22 #include "FMedia_AudioManagerConvert.h"
23
24
25 using namespace Tizen::Base;
26 using namespace Tizen::Base::Collection;
27 using namespace Tizen::Base::Runtime;
28 namespace Tizen{ namespace Media{
29
30 _AudioSessionManagerImpl* _AudioSessionManagerImpl::__pAudioSessionImpl = null;
31
32 void
33 _AudioSessionManagerImpl::InitAudioSessionManagerImpl(void)
34 {
35         static _AudioSessionManagerImpl instance;
36         __pAudioSessionImpl = &instance;
37 }
38
39 _AudioSessionManagerImpl*
40 _AudioSessionManagerImpl::GetInstance()
41 {
42         result r = E_SUCCESS;
43         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
44         if (__pAudioSessionImpl == null)
45         {
46                 pthread_once(&onceBlock, InitAudioSessionManagerImpl);
47                 r = __pAudioSessionImpl->Construct();
48                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, ,r, "[%s] Propagating.", GetErrorMessage(r));
49         }
50         return __pAudioSessionImpl;
51 CATCH:
52         __pAudioSessionImpl = null;
53         return null;
54 }
55
56 result
57 _AudioSessionManagerImpl::Construct(void)
58 {
59         result r = E_SUCCESS;
60         int ret = 0;
61
62         __pAudioSessionEvent.reset(new (std::nothrow) _AudioSessionEvent);
63         SysTryCatch(NID_MEDIA, __pAudioSessionEvent.get(), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
64         r = __pAudioSessionEvent->Construct();
65         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
66
67         ret = sound_manager_set_interrupted_cb(SoundSessionNotificationsCallback, (void*)this);
68         SysTryCatch(NID_MEDIA, ret == SOUND_MANAGER_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
69                 "[E_SYSTEM] A system error has been occurred. Failed to perform sound_manager_set_interrupted_cb operation with error code : 0x%x", ret);
70         return r;
71 CATCH:
72         return r;
73 }
74
75 _AudioSessionManagerImpl::_AudioSessionManagerImpl()
76         : __pSingleAudioSessionListner(null)
77         , __currentSessionMode(AUDIO_SESSION_MODE_SHARED)
78         , __interruptedEvent(SOUND_INTERRUPTED_BY_MEDIA)
79         , __interruptFlag(false)
80 {
81
82 }
83
84 _AudioSessionManagerImpl::~_AudioSessionManagerImpl()
85 {
86         sound_manager_unset_interrupted_cb();
87         __pSingleAudioSessionListner = null;
88         __pAudioSessionImpl = null;
89 }
90
91 result
92 _AudioSessionManagerImpl::AddListener(IAudioSessionEventListener *pListener)
93 {
94         SysTryReturn(NID_MEDIA, pListener != null, E_INVALID_ARG, E_INVALID_ARG,
95                 "[E_INVALID_ARG] Invalid argument is used. The value of pListener is null.");
96         return __pAudioSessionEvent->AddListener(*pListener);
97 }
98
99 result
100 _AudioSessionManagerImpl::SetAudioSessionEventListener(IAudioSessionEventListener* pListener)
101 {
102         result r = E_SUCCESS;
103         SysTryReturn(NID_MEDIA, __pAudioSessionEvent.get() != null, E_INVALID_OPERATION, E_INVALID_OPERATION,
104                 "[E_INVALID_OPERATION] A error has been occurred. The value of __pAudioSessionEvent is null.");
105         if (__pSingleAudioSessionListner != null)
106         {
107                 r = __pAudioSessionEvent->RemoveListener(*__pSingleAudioSessionListner);
108                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] RemoveListener() failed", GetErrorMessage(r));
109                 __pSingleAudioSessionListner = null;
110         }
111         if (pListener != null)
112         {
113                 r = __pAudioSessionEvent->AddListener(*pListener);
114                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] AddListener() failed", GetErrorMessage(r));
115                 __pSingleAudioSessionListner = pListener;
116         }
117         return r;
118 }
119
120 result
121 _AudioSessionManagerImpl::RemoveListener(IAudioSessionEventListener *pListener)
122 {
123         return __pAudioSessionEvent->RemoveListener(*pListener);
124 }
125
126
127 result
128 _AudioSessionManagerImpl::SetMode(AudioSessionMode sessionMode)
129 {
130         result r = E_SUCCESS;
131         int ret = SOUND_MANAGER_ERROR_NONE;
132         ret = sound_manager_set_session_type(_AudioManagerConvert::ConvertAudioSession2SoundSession(sessionMode));
133         r = _AudioManagerConvert::CovertSoundManagerError2Result(ret);
134         SysTryReturnResult(NID_MEDIA, r == E_SUCCESS, r,
135                 "Failed to perform sound_manager_set_session_type operation with error code : 0x%x", ret);
136         __currentSessionMode = sessionMode;
137         return r;
138
139 }
140
141 AudioSessionMode
142 _AudioSessionManagerImpl::GetMode(void)
143 {
144         result r = E_SUCCESS;
145         int ret = SOUND_MANAGER_ERROR_NONE;
146         sound_session_type_e soundSession = SOUND_SESSION_TYPE_SHARE;
147         ret = sound_manager_get_session_type(&soundSession);
148         r = _AudioManagerConvert::CovertSoundManagerError2Result(ret);
149         SysTryCatch(NID_MEDIA, r == E_SUCCESS, ,r, "[%s] Propagating.", GetErrorMessage(r));
150         return _AudioManagerConvert::ConvertSoundSession2AudioSession(soundSession);
151 CATCH:
152         //return default session type
153         return AUDIO_SESSION_MODE_SHARED;
154 }
155
156 sound_interrupted_code_e
157 _AudioSessionManagerImpl::GetInterruptType(void)
158 {
159         return __interruptedEvent;
160 }
161
162 void
163 _AudioSessionManagerImpl::SoundSessionNotificationsCallback(sound_interrupted_code_e notify, void* pUserData)
164 {
165         SysLog(NID_MEDIA, "This instance received message code : %d", notify);
166         _AudioSessionManagerImpl *pAudioSessionManagerImpl = (_AudioSessionManagerImpl *)pUserData;
167
168         switch (notify)
169         {
170         case SOUND_INTERRUPTED_COMPLETED:
171                 if (!(pAudioSessionManagerImpl->__interruptFlag))
172                 {
173                         __pAudioSessionImpl->SendReleased();
174                 }
175                 pAudioSessionManagerImpl->__interruptFlag = false;
176                 break;
177         case SOUND_INTERRUPTED_BY_CALL:
178                 pAudioSessionManagerImpl->__interruptFlag = true;
179                 //fall through
180         case SOUND_INTERRUPTED_BY_MEDIA:
181                 //fall through
182         case SOUND_INTERRUPTED_BY_RESOURCE_CONFLICT:
183                 //fall through
184         case SOUND_INTERRUPTED_BY_EARJACK_UNPLUG:
185                 __pAudioSessionImpl->SendAudioFocusChanged(notify);
186                 break;
187         case SOUND_INTERRUPTED_BY_EMERGENCY:
188                 //fall through
189         case SOUND_INTERRUPTED_BY_ALARM:
190                 __pAudioSessionImpl->SendInterrupted(notify);
191                 break;
192         default:
193                 SysLogException(NID_MEDIA, E_SYSTEM, "A system error occurred. Invalid notify signal is %d",notify);
194                 break;
195         }
196 }
197
198 void
199 _AudioSessionManagerImpl::SendInterrupted(sound_interrupted_code_e notify)
200 {
201         result r = E_SUCCESS;
202         _AudioSessionEventArg* pAudioSessionEventArg = new (std::nothrow) _AudioSessionEventArg;
203         SysTryReturn(NID_MEDIA, pAudioSessionEventArg, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
204         pAudioSessionEventArg->SetEventType(_AUDIO_SESSION_EVENT_INTERRUPTED);
205         __interruptedEvent = notify;
206         r = __pAudioSessionEvent->FireAsync(*pAudioSessionEventArg);
207         SysTryLog(NID_MEDIA, r == E_SUCCESS, "[%s] Failed to perform FireAsync operation.", GetErrorMessage(r));
208 }
209
210 void
211 _AudioSessionManagerImpl::SendAudioFocusChanged(sound_interrupted_code_e notify)
212 {
213         result r = E_SUCCESS;
214         _AudioSessionEventArg* pAudioSessionEventArg = new (std::nothrow) _AudioSessionEventArg;
215         SysTryReturn(NID_MEDIA, pAudioSessionEventArg, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
216         pAudioSessionEventArg->SetEventType(_AUDIO_SESSION_EVENT_AUDIO_FOCUS_CHANGED);
217         __interruptedEvent = notify;
218         r = __pAudioSessionEvent->FireAsync(*pAudioSessionEventArg);
219         SysTryLog(NID_MEDIA, r == E_SUCCESS, "[%s]Failed to perform FireAsync operation.", GetErrorMessage(r));
220 }
221
222 void
223 _AudioSessionManagerImpl::SendReleased()
224 {
225         result r = E_SUCCESS;
226         _AudioSessionEventArg* pAudioSessionEventArg = new (std::nothrow) _AudioSessionEventArg;
227         SysTryReturn(NID_MEDIA, pAudioSessionEventArg, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
228         pAudioSessionEventArg->SetEventType(_AUDIO_SESSION_EVENT_RELEASED);
229         r = __pAudioSessionEvent->FireAsync(*pAudioSessionEventArg);
230         SysTryLog(NID_MEDIA, r == E_SUCCESS, "[%s] Failed to perform FireAsync operation.", GetErrorMessage(r));
231 }
232
233 }
234 }