Update contrib.
1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "MmfBtAudioPolicy.h"
17 #include "MmfBtAudioPolicySession.h"
18 #include "MmfBtAudioPolicyServer.h"
19 #include "MdaBtHwInfo.h"
20 #include "MmfBtAudioPolicyRequest.h"
22 CAudioPolicy::~CAudioPolicy()
25 delete iAudioPolicyRequestArray;
28 void CAudioPolicy::ConstructL()
30 // Create dynamic array for sessions list
31 iAudioPolicyRequestArray = new(ELeave)CArrayFixFlat<CMMFAudioPolicyRequest>(CAudioPolicy::EGranularity);
32 iMdaHwInfo = CMdaHwInfo::NewL();
35 EXPORT_C CAudioPolicy* CAudioPolicy::NewL(CMMFAudioPolicyServer* aAudioPolicyServer)
38 CAudioPolicy* self = new(ELeave)CAudioPolicy(aAudioPolicyServer);
39 CleanupStack::PushL(self);
45 CAudioPolicy::CAudioPolicy(CMMFAudioPolicyServer* aAudioPolicyServer) :
46 iAudioPolicyServer(aAudioPolicyServer)
50 void CAudioPolicy::MakeRequest(CMMFAudioPolicyRequest* aAudioPolicyRequest)
52 //Make sure there is sufficient space in the array to avoid expansion in AppendL()
53 __ASSERT_ALWAYS(iAudioPolicyRequestArray->Count() < iAudioPolicyServer->PolicySessionCount(), Panic(EMMFAudioPolicyRequestArrayOverflow));
54 TPolicyResponse responseValue;
55 iSessionToAlert = NULL; // Reset
57 // Process Request by looking at priorities, preferences, special states...
58 responseValue = ProcessRequest(aAudioPolicyRequest);
60 // Finally, check current profile settings (only if not denied thus far):
61 // CheckAgainstProfiles(aAudioPolicyRequest, responseValue);
62 if (responseValue == EDenied)
64 SetSessionToAlert(aAudioPolicyRequest->PolicySessionId(),
65 NULL, TMMFAudioPolicyEvent::EMMFAudioPolicyPriorityTooLow,
66 aAudioPolicyRequest->State());
67 if(IsRegisteredNotification(aAudioPolicyRequest->PolicySessionId()))
69 TRAPD(err, iAudioPolicyRequestArray->AppendL(*aAudioPolicyRequest) );
70 __ASSERT_ALWAYS(err==KErrNone, Panic(EMMFAudioPolicyRequestArrayOverflow) ); // we reserved space, so shouldn't hit this
74 // If a client needs to be notified (either a previous session that was booted off or a new
75 // one that was denied) then send event for that session to the client:
76 // NB KErrInUse, KErrDied OR KErrAccessDenied may be used to indicate this.
77 if (iSessionToAlert != NULL)
79 //check the session is registered for notification of resource available
80 if(!IsRegisteredNotification(iSessionToAlert))
82 RemoveFromList(iSessionToAlert);
84 iAudioPolicyEvent.iErrorCode = KErrInUse;
85 iAudioPolicyEvent.iState = aAudioPolicyRequest->State();
86 iAudioPolicyServer->SendEventToClient(iSessionToAlert, iSessionToBeLaunched, iAudioPolicyEvent);
88 //Resume of a Audio of the notified client ,since it is already in the list
89 //no need to append and send response back to DevSound for request accepted.
90 if(responseValue == EResume)
92 iAudioPolicyServer->StopNotificationTimer();
93 iAudioPolicyEvent.iErrorCode = KErrNone;
94 iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyNoEvent;
95 iAudioPolicyEvent.iState = aAudioPolicyRequest->State();
96 iAudioPolicyServer->SendEventToClient(aAudioPolicyRequest->PolicySessionId(), NULL, iAudioPolicyEvent);
98 // Add new policy to list, and send response back to DevSound for request accepted
99 if (responseValue == EProceed)
101 //no possibility of expansion here as sufficient space for the array is reserved in advance during the creation of the policysession
102 TRAPD(err, iAudioPolicyRequestArray->AppendL(*aAudioPolicyRequest) );
103 __ASSERT_ALWAYS(err==KErrNone,Panic(EMMFAudioPolicyRequestArrayOverflow) ); // we reserved space, so shouldn't hit this
104 iAudioPolicyEvent.iErrorCode = KErrNone;
105 iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyNoEvent;
106 iAudioPolicyEvent.iState = aAudioPolicyRequest->State();
107 iAudioPolicyServer->SendEventToClient(aAudioPolicyRequest->PolicySessionId(), NULL, iAudioPolicyEvent);
109 if (responseValue == EStopThenProceed) // place on list, but dev Sound will launch request
111 //no possibility of expansion here as sufficient space for the array is reserved in advance during the creation of the policysession
112 TRAPD(err, iAudioPolicyRequestArray->AppendL(*aAudioPolicyRequest) );
113 __ASSERT_ALWAYS(err==KErrNone,Panic(EMMFAudioPolicyRequestArrayOverflow) ); // we reserved space, so shouldn't hit this
117 TPolicyResponse CAudioPolicy::ProcessRequest(CMMFAudioPolicyRequest* aAudioPolicyRequest)
119 TPolicyResponse responseValue(EProceed);
120 iSessionToAlert = NULL; // Reset
122 // If there is no other item on list, return with proceed
123 if (!iAudioPolicyRequestArray->Count())
126 // Handle Preferences, if any, otherwise just compare priorities:
127 // HandlePreferences(aAudioPolicyRequest, preference, responseValue);
132 responseValue = ComparePriorities(aAudioPolicyRequest);
134 return responseValue;
137 void CAudioPolicy::ModifyEntry(TInt aPolicySessionId, CMMFAudioPolicyRequest* aAudioPolicyRequest)
139 TMMFAudioPolicyState requestState = aAudioPolicyRequest->State();
140 // If state is stopped or paused, remove item from list
141 if ((aAudioPolicyRequest->State() == EMMFStatePaused) || (aAudioPolicyRequest->State() == EMMFStateStopped) || (aAudioPolicyRequest->State() == EMMFStateCompleted))
143 if(iSessionToBeLaunched == aPolicySessionId)
145 iSessionToBeLaunched = 0;
147 if((aAudioPolicyRequest->State() == EMMFStateStopped) && (!iSessionToBeLaunched))
149 TInt sessionToNotify = CheckSessionToNotify();
152 iAudioPolicyServer->StartNotificationTimer();
153 iAudioPolicyEvent.iErrorCode = KErrNone;
154 iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyResourceNotification;
155 iAudioPolicyServer->SendEventToClient(sessionToNotify, NULL, iAudioPolicyEvent);
158 if(aAudioPolicyRequest->NotificationEvent() != KMMFEventCategoryAudioResourceAvailable)
160 RemoveFromList(aPolicySessionId);
165 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
167 // Find correct entry to replace state
168 if ( ((*iAudioPolicyRequestArray)[index].PolicySessionId()) == aPolicySessionId)
170 (*iAudioPolicyRequestArray)[index].SetState(requestState);
176 void CAudioPolicy::RemoveFromList(TInt aPolicySessionId)
178 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
180 // Find correct entry to remove
181 if ( (*iAudioPolicyRequestArray)[index].PolicySessionId() == aPolicySessionId)
183 iAudioPolicyRequestArray->Delete(index);
189 TPolicyResponse CAudioPolicy::ComparePriorities(CMMFAudioPolicyRequest* aAudioPolicyRequest/*, TMMFAudioPolicyEvent& aEvent*/)
191 TPolicyResponse responseValue(EProceed);
192 TInt requestPriority = aAudioPolicyRequest->Priority();
194 TBool requestCaps = aAudioPolicyRequest->Capabilities();
196 // Iterate through list and compare priorities:
197 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
199 // If there's even one on the list w/ a higher priority deny request and leave:
201 if ((*iAudioPolicyRequestArray)[index].Capabilities() > requestCaps)
203 responseValue = EDenied;
206 else if((*iAudioPolicyRequestArray)[index].Capabilities() == requestCaps)
208 if((*iAudioPolicyRequestArray)[index].Priority() >= requestPriority)
210 responseValue = EDenied;
216 // Otherwise have the one on the list removed:
217 SetSessionToAlert((*iAudioPolicyRequestArray)[index].PolicySessionId(),
218 aAudioPolicyRequest->PolicySessionId(), TMMFAudioPolicyEvent::EMMFAudioPolicyPriorityTooLow, aAudioPolicyRequest->State());
219 responseValue = EStopThenProceed;
221 return responseValue;
224 void CAudioPolicy::HandlePreferences(CMMFAudioPolicyRequest* /*aAudioPolicyRequest*/, TInt /*aPref*/, TPolicyResponse& /*aResponse*/)
228 void CAudioPolicy::LaunchRequest()
230 if (iAudioPolicyEventToLaunch.iEventType == TMMFAudioPolicyEvent::EMMFAudioPolicySwitchToIdle)
231 iAudioPolicyServer->LaunchRequest(iSessionToBeLaunched, iAudioPolicyEventToLaunch);
234 // Sets up session information for sending an event on a denied (or killed) request
235 void CAudioPolicy::SetSessionToAlert(TInt aSessionToAlert, TInt aSessionToBeLaunched, TMMFAudioPolicyEvent::TAudioPolicyEventType aEventType, TMMFAudioPolicyState aState )
237 iSessionToAlert = aSessionToAlert;
238 iSessionToBeLaunched = aSessionToBeLaunched;
239 iAudioPolicyEvent.iEventType = aEventType;
241 if (iSessionToBeLaunched != 0) // When currently playing item needs to be stopped
243 iAudioPolicyEventToLaunch.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicySwitchToIdle;
244 iAudioPolicyEventToLaunch.iState = aState;
248 CArrayFixFlat<CMMFAudioPolicyRequest>* CAudioPolicy::AudioPolicyRequestArray()
250 return iAudioPolicyRequestArray;
256 This function raises a panic
259 one of the several panics codes that may be raised by this dll
261 @panic EMMFAudioPolicyRequestArrayOverflow is raised when policyrequest array is full
263 GLDEF_C void Panic(TMMFAudioPolicyPanicCodes aPanicCode)
265 User::Panic(KMMFAudioPolicyPanicCategory, aPanicCode);
268 // checks based on the session ,Is the session is registered for Notification
269 TBool CAudioPolicy::IsRegisteredNotification(TInt aSessionId)
272 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
274 if((*iAudioPolicyRequestArray)[index].PolicySessionId() == aSessionId)
276 event = (*iAudioPolicyRequestArray)[index].NotificationEvent();
277 if (event == KMMFEventCategoryAudioResourceAvailable)
279 // only when the client is registered for KMMFEventCategoryAudioResourceAvailable event
288 // checks the state,whether any client is already send notification
289 TBool CAudioPolicy::IsNotified()
291 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
293 if((*iAudioPolicyRequestArray)[index].State() == EMMFStateNotified)
295 // In a instance only one client should have the state as EMMFStateNotified
302 // get the next highest priority of the client to notify
303 TInt CAudioPolicy::CheckSessionToNotify()
305 TInt nextHighestPriority= -100;
306 TInt sessionToNotify = 0;
307 TInt notificationIdx = -1;
310 return sessionToNotify;
312 // get the max priority and set the Index
313 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
315 if((nextHighestPriority <= (*iAudioPolicyRequestArray)[index].Priority()) && ((*iAudioPolicyRequestArray)[index].NotificationEvent() != KNullUid) && (!(*iAudioPolicyRequestArray)[index].IsEventNotified()))
317 nextHighestPriority = (*iAudioPolicyRequestArray)[index].Priority();
318 sessionToNotify = (*iAudioPolicyRequestArray)[index].PolicySessionId();
319 notificationIdx = index;
322 // set the state as notified
323 if(notificationIdx != -1)
325 (*iAudioPolicyRequestArray)[notificationIdx].SetEventFlag(ETrue);
326 (*iAudioPolicyRequestArray)[notificationIdx].SetState(EMMFStateNotified);
328 return sessionToNotify;
331 // send the message to the server
332 void CAudioPolicy::DoSendNotification()
335 TInt sessionToNotify = CheckSessionToNotify();
338 iAudioPolicyEvent.iErrorCode = KErrNone;
339 iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyResourceNotification;
340 iAudioPolicyServer->SendEventToClient(sessionToNotify, NULL, iAudioPolicyEvent);
344 // Set in the AudiopolicyRequestArray the uid registered
345 TInt CAudioPolicy::SetNotification(TInt aSessionId, TUid aEventType)
347 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
349 if((*iAudioPolicyRequestArray)[index].PolicySessionId() == aSessionId)
351 (*iAudioPolicyRequestArray)[index].SetNotificationEvent(aEventType);
358 // cancel the state of the message notification to closed
359 void CAudioPolicy::ResetNotification()
361 for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
363 if((*iAudioPolicyRequestArray)[index].State() == EMMFStateNotified)
365 (*iAudioPolicyRequestArray)[index].SetState(EMMFStateClosed);