devsound/sounddevbt/src/server/Policy/MmfBtAudioPolicy.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "MmfBtAudioPolicy.h"
       
    17 #include "MmfBtAudioPolicySession.h"	
       
    18 #include "MmfBtAudioPolicyServer.h"
       
    19 #include "MdaBtHwInfo.h"	
       
    20 #include "MmfBtAudioPolicyRequest.h"
       
    21 
       
    22 CAudioPolicy::~CAudioPolicy()
       
    23 	{
       
    24 	delete iMdaHwInfo;
       
    25 	delete iAudioPolicyRequestArray; 		
       
    26 	}
       
    27 
       
    28 void CAudioPolicy::ConstructL()
       
    29 	{
       
    30 	// Create dynamic array for sessions list
       
    31 	iAudioPolicyRequestArray = new(ELeave)CArrayFixFlat<CMMFAudioPolicyRequest>(CAudioPolicy::EGranularity);
       
    32 	iMdaHwInfo = CMdaHwInfo::NewL();
       
    33 	}
       
    34 
       
    35 EXPORT_C CAudioPolicy* CAudioPolicy::NewL(CMMFAudioPolicyServer* aAudioPolicyServer)
       
    36 	{	
       
    37 
       
    38 	CAudioPolicy* self = new(ELeave)CAudioPolicy(aAudioPolicyServer);
       
    39 	CleanupStack::PushL(self);
       
    40 	self->ConstructL();
       
    41 	CleanupStack::Pop();
       
    42 	return(self);
       
    43 	}
       
    44 
       
    45 CAudioPolicy::CAudioPolicy(CMMFAudioPolicyServer* aAudioPolicyServer) :
       
    46 	iAudioPolicyServer(aAudioPolicyServer)
       
    47 	{
       
    48 	}
       
    49 
       
    50 void CAudioPolicy::MakeRequest(CMMFAudioPolicyRequest* aAudioPolicyRequest)
       
    51 	{
       
    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
       
    56 
       
    57 	// Process Request by looking at priorities, preferences, special states...
       
    58 	responseValue = ProcessRequest(aAudioPolicyRequest);
       
    59 
       
    60 		// Finally, check current profile settings (only if not denied thus far):
       
    61 		//	CheckAgainstProfiles(aAudioPolicyRequest, responseValue);
       
    62 		if (responseValue == EDenied)
       
    63 			{
       
    64 			SetSessionToAlert(aAudioPolicyRequest->PolicySessionId(),
       
    65 							  NULL, TMMFAudioPolicyEvent::EMMFAudioPolicyPriorityTooLow,
       
    66 							  aAudioPolicyRequest->State());
       
    67 			if(IsRegisteredNotification(aAudioPolicyRequest->PolicySessionId()))
       
    68 				{
       
    69 				TRAPD(err, iAudioPolicyRequestArray->AppendL(*aAudioPolicyRequest) );
       
    70 				__ASSERT_ALWAYS(err==KErrNone, Panic(EMMFAudioPolicyRequestArrayOverflow) ); // we reserved space, so shouldn't hit this
       
    71 				}
       
    72 			}
       
    73 
       
    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)
       
    78 		{
       
    79 			//check the session is registered for notification of resource available
       
    80 			if(!IsRegisteredNotification(iSessionToAlert))
       
    81 				{
       
    82 				RemoveFromList(iSessionToAlert);  				
       
    83 				}
       
    84 			iAudioPolicyEvent.iErrorCode = KErrInUse;
       
    85 			iAudioPolicyEvent.iState = aAudioPolicyRequest->State();
       
    86 			iAudioPolicyServer->SendEventToClient(iSessionToAlert, iSessionToBeLaunched, iAudioPolicyEvent);
       
    87 		}
       
    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)
       
    91 			{
       
    92 			iAudioPolicyServer->StopNotificationTimer();
       
    93 			iAudioPolicyEvent.iErrorCode = KErrNone;
       
    94 			iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyNoEvent;
       
    95 			iAudioPolicyEvent.iState = aAudioPolicyRequest->State();
       
    96 			iAudioPolicyServer->SendEventToClient(aAudioPolicyRequest->PolicySessionId(), NULL, iAudioPolicyEvent);	
       
    97 			}
       
    98 		// Add new policy to list, and send response back to DevSound for request accepted
       
    99 	if (responseValue == EProceed)
       
   100 		{
       
   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);
       
   108 		}
       
   109 	if (responseValue == EStopThenProceed)  // place on list, but dev Sound will launch request
       
   110 		{
       
   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
       
   114 		}
       
   115 	}
       
   116 
       
   117 TPolicyResponse CAudioPolicy::ProcessRequest(CMMFAudioPolicyRequest* aAudioPolicyRequest)
       
   118 	{
       
   119 	TPolicyResponse responseValue(EProceed); 
       
   120 	iSessionToAlert = NULL; // Reset
       
   121 
       
   122 	// If there is no other item on list, return with proceed
       
   123 	if (!iAudioPolicyRequestArray->Count()) 
       
   124 		return EProceed;
       
   125 	
       
   126 	// Handle Preferences, if any, otherwise just compare priorities:
       
   127 	//	HandlePreferences(aAudioPolicyRequest, preference, responseValue);
       
   128 	if(IsNotified())
       
   129 		{
       
   130 		return EResume;
       
   131 		}
       
   132 	responseValue = ComparePriorities(aAudioPolicyRequest);
       
   133 
       
   134 	return responseValue;
       
   135 	}
       
   136 
       
   137 void CAudioPolicy::ModifyEntry(TInt aPolicySessionId, CMMFAudioPolicyRequest* aAudioPolicyRequest)
       
   138 	{
       
   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))
       
   142 		{
       
   143 		if(iSessionToBeLaunched == aPolicySessionId)
       
   144 			{
       
   145 			iSessionToBeLaunched = 0;
       
   146 			}
       
   147 		if((aAudioPolicyRequest->State() == EMMFStateStopped) && (!iSessionToBeLaunched))
       
   148 			{	
       
   149 			TInt sessionToNotify = CheckSessionToNotify();
       
   150 			if(sessionToNotify)
       
   151 				{
       
   152 				iAudioPolicyServer->StartNotificationTimer();
       
   153 				iAudioPolicyEvent.iErrorCode = KErrNone;
       
   154 				iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyResourceNotification;
       
   155 				iAudioPolicyServer->SendEventToClient(sessionToNotify, NULL, iAudioPolicyEvent);
       
   156 				}	
       
   157 			}
       
   158 			if(aAudioPolicyRequest->NotificationEvent() != KMMFEventCategoryAudioResourceAvailable)
       
   159 				{
       
   160 				RemoveFromList(aPolicySessionId);	
       
   161 				return;
       
   162 				}
       
   163 		}
       
   164 	
       
   165 	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   166 		{
       
   167 			// Find correct entry to replace state	
       
   168 			if ( ((*iAudioPolicyRequestArray)[index].PolicySessionId()) == aPolicySessionId)
       
   169 				{
       
   170 					(*iAudioPolicyRequestArray)[index].SetState(requestState);
       
   171 					break;
       
   172 				}
       
   173 		}  
       
   174 	}
       
   175 
       
   176 void CAudioPolicy::RemoveFromList(TInt aPolicySessionId)
       
   177 	{
       
   178 	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   179 		{
       
   180 			// Find correct entry to remove	
       
   181 			if ( (*iAudioPolicyRequestArray)[index].PolicySessionId() == aPolicySessionId)
       
   182 				{
       
   183 					iAudioPolicyRequestArray->Delete(index);
       
   184 					break;
       
   185 				}
       
   186 		}  
       
   187 	}
       
   188 	
       
   189 TPolicyResponse CAudioPolicy::ComparePriorities(CMMFAudioPolicyRequest* aAudioPolicyRequest/*, TMMFAudioPolicyEvent& aEvent*/)
       
   190 	{
       
   191 	TPolicyResponse responseValue(EProceed);
       
   192 	TInt requestPriority = aAudioPolicyRequest->Priority();
       
   193 
       
   194 	TBool requestCaps = aAudioPolicyRequest->Capabilities();
       
   195 
       
   196 	// Iterate through list and compare priorities:
       
   197 	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   198 		{
       
   199 			// If there's even one on the list w/ a higher priority deny request and leave:
       
   200 
       
   201 			if ((*iAudioPolicyRequestArray)[index].Capabilities() > requestCaps)
       
   202 				{
       
   203 				responseValue = EDenied;
       
   204 				break;
       
   205 				}
       
   206 			else if((*iAudioPolicyRequestArray)[index].Capabilities() == requestCaps) 
       
   207 				{
       
   208 					if((*iAudioPolicyRequestArray)[index].Priority() >= requestPriority)
       
   209 					{
       
   210 						responseValue = EDenied;
       
   211 						break;
       
   212 					}
       
   213 				}
       
   214 
       
   215 
       
   216 			// Otherwise have the one on the list removed:
       
   217 				SetSessionToAlert((*iAudioPolicyRequestArray)[index].PolicySessionId(), 
       
   218 					aAudioPolicyRequest->PolicySessionId(), TMMFAudioPolicyEvent::EMMFAudioPolicyPriorityTooLow, aAudioPolicyRequest->State());
       
   219 				responseValue = EStopThenProceed;
       
   220 		}    
       
   221 	return responseValue;
       
   222 	}
       
   223 
       
   224 void CAudioPolicy::HandlePreferences(CMMFAudioPolicyRequest* /*aAudioPolicyRequest*/, TInt /*aPref*/, TPolicyResponse& /*aResponse*/)
       
   225 	{
       
   226 	}
       
   227 
       
   228 void CAudioPolicy::LaunchRequest()
       
   229 	{
       
   230 	if (iAudioPolicyEventToLaunch.iEventType == TMMFAudioPolicyEvent::EMMFAudioPolicySwitchToIdle)
       
   231 		iAudioPolicyServer->LaunchRequest(iSessionToBeLaunched, iAudioPolicyEventToLaunch);
       
   232 	}
       
   233 
       
   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 )
       
   236 	{
       
   237 	iSessionToAlert = aSessionToAlert;
       
   238 	iSessionToBeLaunched = aSessionToBeLaunched;
       
   239 	iAudioPolicyEvent.iEventType = aEventType;
       
   240 
       
   241 	if (iSessionToBeLaunched != 0)  // When currently playing item needs to be stopped
       
   242 		{
       
   243 		iAudioPolicyEventToLaunch.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicySwitchToIdle;
       
   244 		iAudioPolicyEventToLaunch.iState = aState;
       
   245 		}
       
   246 	}
       
   247 
       
   248 CArrayFixFlat<CMMFAudioPolicyRequest>* CAudioPolicy::AudioPolicyRequestArray()
       
   249 	{
       
   250 	return iAudioPolicyRequestArray;
       
   251 	}
       
   252 	
       
   253 /**
       
   254 @internalTechnology
       
   255 
       
   256 This function raises a panic
       
   257 
       
   258 @param	aError
       
   259 		one of the several panics codes that may be raised by this dll
       
   260 
       
   261 @panic	EMMFAudioPolicyRequestArrayOverflow is raised when policyrequest array is full
       
   262 */
       
   263 GLDEF_C void Panic(TMMFAudioPolicyPanicCodes aPanicCode)
       
   264 	{
       
   265 	User::Panic(KMMFAudioPolicyPanicCategory, aPanicCode);
       
   266 	}
       
   267 
       
   268 // checks based on the session ,Is the session is registered for Notification 
       
   269 TBool CAudioPolicy::IsRegisteredNotification(TInt aSessionId)
       
   270 	{
       
   271 	TUid event;
       
   272  	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   273  		{
       
   274  		if((*iAudioPolicyRequestArray)[index].PolicySessionId() == aSessionId)
       
   275  			{
       
   276  			event = (*iAudioPolicyRequestArray)[index].NotificationEvent();
       
   277  			if (event  == KMMFEventCategoryAudioResourceAvailable)
       
   278  				{
       
   279  				// only when the client is registered for KMMFEventCategoryAudioResourceAvailable event
       
   280  				return ETrue; 
       
   281  				}
       
   282  			break;	
       
   283  			} 
       
   284  		} 
       
   285  	return EFalse;
       
   286 	}
       
   287 
       
   288 // checks the state,whether any client is already send notification
       
   289 TBool CAudioPolicy::IsNotified()
       
   290 	{
       
   291  	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   292  		{
       
   293 		if((*iAudioPolicyRequestArray)[index].State() == EMMFStateNotified)
       
   294 			{
       
   295 			// In a instance only one client should have the state as EMMFStateNotified
       
   296 			return ETrue;
       
   297 			}
       
   298  		}
       
   299  	return EFalse;
       
   300 	}
       
   301 
       
   302 // get the next highest priority of the client to notify 	
       
   303 TInt CAudioPolicy::CheckSessionToNotify()
       
   304 	{
       
   305 	TInt nextHighestPriority= -100;
       
   306 	TInt sessionToNotify = 0;
       
   307 	TInt notificationIdx = -1;
       
   308 	if(IsNotified())
       
   309 		{
       
   310 		return sessionToNotify;
       
   311 		}
       
   312 	// get the max priority and set the Index 		
       
   313 	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   314  		{
       
   315  		if((nextHighestPriority <= (*iAudioPolicyRequestArray)[index].Priority()) && ((*iAudioPolicyRequestArray)[index].NotificationEvent() != KNullUid) && (!(*iAudioPolicyRequestArray)[index].IsEventNotified()))
       
   316  			{
       
   317  			nextHighestPriority = (*iAudioPolicyRequestArray)[index].Priority();
       
   318  			sessionToNotify = (*iAudioPolicyRequestArray)[index].PolicySessionId();
       
   319  			notificationIdx = index;
       
   320  			}
       
   321  		}
       
   322  	// set the state as notified	
       
   323  	if(notificationIdx != -1)
       
   324  		{
       
   325  		(*iAudioPolicyRequestArray)[notificationIdx].SetEventFlag(ETrue);	
       
   326  		(*iAudioPolicyRequestArray)[notificationIdx].SetState(EMMFStateNotified);	
       
   327  		}
       
   328   	return sessionToNotify;	
       
   329 	}
       
   330 
       
   331 // send the message to the server 
       
   332 void CAudioPolicy::DoSendNotification()
       
   333 	{
       
   334 	ResetNotification();
       
   335 	TInt sessionToNotify = CheckSessionToNotify();
       
   336 	if(sessionToNotify)
       
   337 		{
       
   338 		iAudioPolicyEvent.iErrorCode = KErrNone;
       
   339 		iAudioPolicyEvent.iEventType = TMMFAudioPolicyEvent::EMMFAudioPolicyResourceNotification;
       
   340 		iAudioPolicyServer->SendEventToClient(sessionToNotify, NULL, iAudioPolicyEvent);
       
   341 		}
       
   342 	}
       
   343 
       
   344 // Set in the AudiopolicyRequestArray the uid registered
       
   345 TInt CAudioPolicy::SetNotification(TInt aSessionId, TUid aEventType)
       
   346 	{
       
   347 	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   348  		{
       
   349  		if((*iAudioPolicyRequestArray)[index].PolicySessionId() == aSessionId)
       
   350  			{
       
   351  			(*iAudioPolicyRequestArray)[index].SetNotificationEvent(aEventType);
       
   352  			return ETrue;	
       
   353  			}
       
   354  		}
       
   355  	return EFalse;
       
   356 	}
       
   357 
       
   358 // cancel the state of the message notification to closed 
       
   359 void 	CAudioPolicy::ResetNotification()
       
   360 	{
       
   361  	for (TInt index = 0; index < iAudioPolicyRequestArray->Count(); index++)
       
   362  		{
       
   363 		if((*iAudioPolicyRequestArray)[index].State() == EMMFStateNotified)
       
   364 			{
       
   365 			(*iAudioPolicyRequestArray)[index].SetState(EMMFStateClosed);
       
   366 			}
       
   367  		}
       
   368  	}
       
   369