commonuisupport/uikon/srvsrc/EIKALSRV.CPP
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 1997-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 // Multialarm version of Alert Server
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include "EIKALSRV.H"
       
    23 
       
    24 // System includes
       
    25 
       
    26 #include "EIKSRV.PAN"
       
    27 #include <eiksrv.h>
       
    28 #include <asaltdefs.h>
       
    29 #include <asshdalarm.h>
       
    30 
       
    31 // User includes
       
    32 #include "EIKALSUP.H"
       
    33 #include "EIKSVFTY.H"
       
    34 #include "EIKPANIC.H"
       
    35 #include "EIKSRV.PAN"
       
    36 
       
    37 
       
    38 // Security constants
       
    39 
       
    40 const TUint8 KPolicyElementSID = 0;
       
    41 
       
    42 const TInt KAlarmServerSid = 0x101f5027;
       
    43 
       
    44 const TUint KRangeCount = 6; 
       
    45 
       
    46 const TInt KEikServAlarmAlertServerRanges[KRangeCount] = 
       
    47 	{	
       
    48 	EASAltOpCodeNotify,		
       
    49 	EASAltOpCodeVisible,	
       
    50 	EASAltOpCodeGetUserTime, 
       
    51 	EASAltOpCodeStartPlayingSound,
       
    52 	EASAltOpCodeGetEndQuietTime,
       
    53 	EASAltOpCodeLast,
       
    54 	};
       
    55 
       
    56 const TUint8 KElementsIndex[KRangeCount] =
       
    57 	{
       
    58 	CPolicyServer::EAlwaysPass,		//Always passing no capability required (Notify, NotifyCancel)
       
    59 	KPolicyElementSID,				//Requires SID to be of Alarmserver ie.0x101f5027 (Visible,SetState, SetAlarm, SetDeferTime)
       
    60 	CPolicyServer::EAlwaysPass,		//Always passing no capability required (GetUserTime, Logon)
       
    61 	KPolicyElementSID,				//Requires SID to be of Alarmserver ie.0x101f5027  (StartPlayingSound, StopPlayingSound, VisibleAll, SetStateAll, StopPlayingSoundAll, DeleteAlarm)
       
    62 	CPolicyServer::EAlwaysPass,		//Always passing no capability required (GetEndQuietTime, GetMaxAlarms)
       
    63 	CPolicyServer::ENotSupported,	//Not Supported		[EASAltOpCodeLast-End]
       
    64 	};
       
    65 
       
    66 const CPolicyServer::TPolicyElement KPolicyElements[] = 
       
    67 	{ 
       
    68 	{_INIT_SECURITY_POLICY_S0(KAlarmServerSid), CPolicyServer::EFailClient} 
       
    69 	};
       
    70 
       
    71 const CPolicyServer::TPolicy KEikServAlarmAlertServerPolicy =
       
    72 	{
       
    73 	CPolicyServer::EAlwaysPass, 
       
    74 	KRangeCount,
       
    75 	KEikServAlarmAlertServerRanges,
       
    76 	KElementsIndex, 	 
       
    77 	KPolicyElements 	
       
    78 	};
       
    79  	
       
    80 
       
    81 //
       
    82 // class CEikServAlarmAlertServer
       
    83 //
       
    84 
       
    85 /**
       
    86 Constructor.
       
    87 */
       
    88 CEikServAlarmAlertServer::CEikServAlarmAlertServer(TInt aPriority, MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) :
       
    89 	CPolicyServer(aPriority, KEikServAlarmAlertServerPolicy),
       
    90 	iAlarmControlFactory(aAlarmControlFactory),
       
    91 	iMaxAlarms(aMaxAlarms)
       
    92 	{
       
    93 	__ASSERT_ALWAYS(aMaxAlarms > 0, Panic(EEsPanicAlarmAlert));	
       
    94 	}
       
    95 
       
    96 /**
       
    97 Creates a new Alert Server.  When an alarm expires, the Alert Server will request an Alarm Control from 
       
    98 the Alarm Control factory.  The number of Alarm Controls at any instance in time will not exceed the specified 
       
    99 maximum limit.
       
   100 
       
   101 @param aAlarmControlFactory Pointer to the Alarm Control factory.  The Alert Server does not take ownership.
       
   102 @param aMaxAlarms Maximum number of concurrent Alarm Controls that the Alarm Control factory will be requested to manufacture.
       
   103 @return Pointer to the Alert Server.
       
   104 */
       
   105 EXPORT_C CEikServAlarmAlertServer* CEikServAlarmAlertServer::NewL(MEikServAlarmFactory* aAlarmControlFactory,  TInt aMaxAlarms)
       
   106 	{
       
   107 	CEikServAlarmAlertServer* server = new (ELeave) CEikServAlarmAlertServer(EActivePriorityIpcEventsHigh, *aAlarmControlFactory, aMaxAlarms);
       
   108 
       
   109 	CleanupStack::PushL(server);
       
   110 	server->StartL(KAlarmAlertServerName);
       
   111 	CleanupStack::Pop(server);
       
   112 	
       
   113 	return server;
       
   114 	}
       
   115 	
       
   116 	
       
   117 /**
       
   118 Creates a new Alert Server.  When an alarm expires, the Alert Server will request an Alarm Control from 
       
   119 the Alarm Control factory.  There is only one Alarm Control at any instance in time.
       
   120 
       
   121 @param aAlarmControlFactory Pointer to the Alarm Control factory.  The Alert Server does not take ownership.
       
   122 @return Pointer to the Alert Server.
       
   123 */	
       
   124 EXPORT_C CEikServAlarmAlertServer* CEikServAlarmAlertServer::NewL(MEikServAlarmFactory* aAlarmControlFactory)
       
   125 	{
       
   126 	return NewL(aAlarmControlFactory, 1);
       
   127 	}
       
   128 			
       
   129 CEikServAlarmAlertServer::~CEikServAlarmAlertServer()
       
   130 	{
       
   131 	iSession = NULL;
       
   132 	}
       
   133 														
       
   134 CSession2* CEikServAlarmAlertServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
       
   135 	{
       
   136 	const TVersion KAlarmAlertServerVersion(KASAltVersionMajor, KASAltVersionMinor, KASAltVersionBuild);
       
   137 	if (iSession)
       
   138 		User::Leave(KErrArgument);	// There should only ever be one session with the alarm alert server.
       
   139 	
       
   140 	if (!User::QueryVersionSupported(KAlarmAlertServerVersion, aVersion) || aVersion.iMajor <=2)  //Current implementation doesn't support old clients 
       
   141 		User::Leave(KErrNotSupported);
       
   142 
       
   143 	CEikServAlarmAlertSession* const session = CEikServAlarmAlertSession::NewL(iAlarmControlFactory, iMaxAlarms);
       
   144 	const_cast<CEikServAlarmAlertServer*>(this)->iSession = session; // iSession does not *own* what it points to
       
   145 	return session;
       
   146 	}
       
   147 
       
   148 
       
   149 EXPORT_C void CEikServAlarmAlertServer::TaskKeyPressedL()
       
   150 	{
       
   151 	if (iSession)
       
   152 		iSession->TaskKeyPressedL();
       
   153 	}
       
   154 
       
   155 
       
   156 EXPORT_C void CEikServAlarmAlertServer::HandleSwitchOnEvent()
       
   157 	{
       
   158 	if (iSession)
       
   159 		iSession->HandleSwitchOnEvent();
       
   160 	}
       
   161 
       
   162 
       
   163 EXPORT_C void CEikServAlarmAlertServer::SetQuietPeriodL(TTime aQuietPeriodEndTime)
       
   164 	{
       
   165 	if (iSession)
       
   166 		iSession->SetQuietPeriodL(aQuietPeriodEndTime);
       
   167 	}
       
   168 
       
   169 
       
   170 EXPORT_C void CEikServAlarmAlertServer::ClearAllAlarmsL()
       
   171 	{
       
   172 	if (iSession)
       
   173 		iSession->ClearAllAlarmsL();
       
   174 	}
       
   175 
       
   176 
       
   177 //
       
   178 // class CEikServAlarmAlertSession
       
   179 //
       
   180 
       
   181 
       
   182 CEikServAlarmAlertSession* CEikServAlarmAlertSession::NewL(MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms)
       
   183 	{
       
   184 	CEikServAlarmAlertSession* const session = new(ELeave) CEikServAlarmAlertSession(aAlarmControlFactory, aMaxAlarms);
       
   185 	CleanupStack::PushL(session);
       
   186 	session->ConstructL();
       
   187 	CleanupStack::Pop(session);
       
   188 	return session;
       
   189 	}
       
   190 
       
   191 
       
   192 CEikServAlarmAlertSession::CEikServAlarmAlertSession(MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) :
       
   193 	iVisible(EFalse), iAlarmControlFactory(aAlarmControlFactory), iMaxAlarms(aMaxAlarms)
       
   194 	{
       
   195 	}
       
   196 	
       
   197 
       
   198 CEikServAlarmAlertSession::~CEikServAlarmAlertSession()
       
   199 	{
       
   200 	CEikServAlarmAlertServer* const server = AlarmAlertServer();
       
   201 	if (server)
       
   202 		server->SessionDied();
       
   203 	
       
   204 	// Delete all the alarm supervisors
       
   205 	const TInt count = iAlarmSupervisors.Count();	
       
   206 	for(TInt i = 0; i < count; i++)
       
   207 		delete iAlarmSupervisors[i];
       
   208 	
       
   209 	iAlarmSupervisors.Reset();
       
   210 	iResponseQueue.Reset();	
       
   211 	}
       
   212 
       
   213 
       
   214 void CEikServAlarmAlertSession::ConstructL()
       
   215 	{
       
   216 	if (iMaxAlarms == 1)
       
   217 		{
       
   218 		CEikAlmControlSupervisor* alarmSupervisor = CEikAlmControlSupervisor::NewLC(iAlarmControlFactory, this);
       
   219 		iAlarmSupervisors.AppendL(alarmSupervisor);
       
   220 		CleanupStack::Pop(alarmSupervisor);
       
   221 		}
       
   222 	}
       
   223 
       
   224 
       
   225 void CEikServAlarmAlertSession::TaskKeyPressedL()
       
   226 	{
       
   227 	const TInt count = iAlarmSupervisors.Count();
       
   228 	for(TInt idx = 0; idx < count; idx++)
       
   229 		{
       
   230 		if (iAlarmSupervisors[idx]->IsVisible())
       
   231 			iAlarmSupervisors[idx]->CmdTaskAwayFromAlarmL();
       
   232 		}		
       
   233 	}
       
   234 
       
   235 
       
   236 void CEikServAlarmAlertSession::HandleSwitchOnEvent()
       
   237 	{
       
   238 	const TInt count = iAlarmSupervisors.Count();
       
   239 	for(TInt idx = 0; idx < count; idx++)
       
   240 		iAlarmSupervisors[idx]->SynchronizeCountDownTimer();
       
   241 	}
       
   242 	
       
   243 
       
   244 void CEikServAlarmAlertSession::ServiceL(const RMessage2 &aMessage)
       
   245 	{
       
   246 	TInt idSlot(0);
       
   247 	TInt idx(0);
       
   248 	
       
   249 	const TInt opCode = aMessage.Function();
       
   250 	switch (opCode)
       
   251 		{
       
   252     case EASAltOpCodeLogon:  //Will be completed automatically when session dies.
       
   253 		break;
       
   254 				
       
   255 	case EASAltOpCodeNotify:
       
   256 		if (!iMessage.IsNull()) // don't accept second pending notification request
       
   257 			{
       
   258 			_LIT(KPanicCategory,"EikSrv-ASAlt");
       
   259 			aMessage.Panic(KPanicCategory, EEsPanicAlarmAlert);
       
   260 			}
       
   261 		else	
       
   262 			{
       
   263 			if (iResponseQueue.Count() == 0)
       
   264 				iMessage = aMessage;
       
   265 			else
       
   266 				{
       
   267 				aMessage.WriteL(0, TPckgC<TAlarmId>(iResponseQueue[0].AlarmId())); 
       
   268 				aMessage.WriteL(1, TPckgC<TTime>(iResponseQueue[0].TimeToSnooze()));
       
   269 				aMessage.Complete(iResponseQueue[0].ResponseCode());
       
   270 				iResponseQueue.Remove(0);
       
   271 				}
       
   272 			}
       
   273 		break;
       
   274     
       
   275     case EASAltOpCodeNotifyCancel:
       
   276     	if (!iMessage.IsNull())
       
   277 			{
       
   278 			iMessage.Complete(KErrCancel);
       
   279 			aMessage.Complete(KErrNone);
       
   280 			}
       
   281 		else 
       
   282 			aMessage.Complete(KErrNone);
       
   283 		break;		
       
   284 		
       
   285 	case EASAltOpCodeSetAlarm:
       
   286 		{
       
   287 		TASShdAlarm alarm;
       
   288 		TPckg<TASShdAlarm> pAlarm(alarm);
       
   289 		aMessage.ReadL(0,pAlarm);
       
   290 
       
   291 		if( (idx = FindAlarm(alarm.Id())) >=0 )
       
   292 			{
       
   293 			iAlarmSupervisors[idx]->ServiceL(aMessage);
       
   294 			aMessage.Complete(KErrNone);
       
   295 			return;
       
   296 			}
       
   297 			
       
   298        	// alarm was not found
       
   299 		if (iAlarmSupervisors.Count() >= iMaxAlarms)
       
   300 			{
       
   301 			// and no room to create new alarm, return KErrNotFound to client to indikate this
       
   302 			aMessage.Complete(KErrNotFound);
       
   303 			return;
       
   304 			}
       
   305 			
       
   306 		CEikAlmControlSupervisor* alarmSupervisor = CEikAlmControlSupervisor::NewLC(iAlarmControlFactory, this);
       
   307 		iAlarmSupervisors.AppendL(alarmSupervisor);
       
   308 		CleanupStack::Pop(alarmSupervisor);
       
   309 		alarmSupervisor->ServiceL(aMessage);
       
   310 		aMessage.Complete(KErrNone);
       
   311 		}
       
   312 		break;		
       
   313 
       
   314 	case EASAltOpCodeGetMaxAlarms:
       
   315 		aMessage.WriteL(0,TPckgC<TInt>(iMaxAlarms)); 
       
   316 		aMessage.Complete(KErrNone);
       
   317 		break;
       
   318 	
       
   319 	case EASAltOpCodeSetState:
       
   320 	case EASAltOpCodeStartPlayingSound:
       
   321 	case EASAltOpCodeVisible:
       
   322 		idSlot = 1;
       
   323 		//fall through
       
   324 	case EASAltOpCodeStopPlayingSound:	
       
   325 		{
       
   326 		const TAlarmId alarmId = (idSlot==0 ? aMessage.Int0() : aMessage.Int1());
       
   327 		if ((idx = FindAlarm(alarmId)) >=0)
       
   328 			{
       
   329 			iAlarmSupervisors[idx]->ServiceL(aMessage);
       
   330 			aMessage.Complete(KErrNone);
       
   331 			}
       
   332 		else  //alarm was not found
       
   333 			aMessage.Complete(KErrNotFound);
       
   334 		}
       
   335 		break;
       
   336 
       
   337 	case EASAltOpCodeVisibleAll:
       
   338 	case EASAltOpCodeSetStateAll:
       
   339 	case EASAltOpCodeStopPlayingSoundAll:
       
   340 		for(idx = 0; idx < iAlarmSupervisors.Count(); idx++)
       
   341 			iAlarmSupervisors[idx]->ServiceL(aMessage);
       
   342 
       
   343 		aMessage.Complete(KErrNone);		
       
   344 		break;
       
   345 
       
   346 	case EASAltOpCodeSetDeferTime:
       
   347 		{
       
   348 		iQuietPeriodEndTime = TTime(MAKE_TUINT64(aMessage.Int1(), aMessage.Int0()));
       
   349 		aMessage.Complete(KErrNone);
       
   350 		}
       
   351 		break;
       
   352 	
       
   353 	case EASAltOpCodeGetEndQuietTime:
       
   354 		aMessage.WriteL(0,TPckgC<TTime>(iQuietPeriodEndTime)); 
       
   355 		aMessage.Complete(KErrNone);
       
   356 		break;
       
   357 	
       
   358 	case EASAltOpCodeDeleteAlarmAll:
       
   359 	case EASAltOpCodeDeleteAlarm:
       
   360 		DeleteAlarmL(aMessage);	
       
   361 		break;
       
   362 	
       
   363 	default:
       
   364 		aMessage.Complete(KErrNotSupported);
       
   365 		break;
       
   366 		}
       
   367 	
       
   368 	UpdateVisibility();
       
   369 	}
       
   370 
       
   371 
       
   372 CEikServAlarmAlertServer* CEikServAlarmAlertSession::AlarmAlertServer() const
       
   373 	{
       
   374 	return static_cast<CEikServAlarmAlertServer*>( const_cast<CServer2*>(Server()) );
       
   375 	}
       
   376 
       
   377 
       
   378 void CEikServAlarmAlertSession::UpdateVisibility()
       
   379 	{
       
   380 	iVisible = EFalse;
       
   381 	
       
   382 	const TInt count = iAlarmSupervisors.Count();
       
   383 	for(TInt i = 0; i < count; i++)
       
   384 		iVisible |= iAlarmSupervisors[i]->IsVisible();
       
   385 	}
       
   386 
       
   387 
       
   388 
       
   389 void CEikServAlarmAlertSession::RespondEventL(TASAltAlertServerResponse aCode)
       
   390 	{
       
   391 	RespondEventL(aCode, KNullAlarmId);
       
   392 	}
       
   393 
       
   394 
       
   395 void CEikServAlarmAlertSession::RespondEventL(TASAltAlertServerResponse aCode, TAlarmId aId, TTime aTimeToSnooze)
       
   396 	{
       
   397 	if (iMessage.IsNull())  // if no request pending
       
   398 		QueueEventL(aCode, aId, aTimeToSnooze); 
       
   399 	else	
       
   400 		{
       
   401 		iMessage.WriteL(0,TPckgC<TAlarmId>(aId)); 
       
   402 		iMessage.WriteL(1,TPckgC<TTime>(aTimeToSnooze));
       
   403 		iMessage.Complete(aCode);
       
   404 		}
       
   405 	}
       
   406 	
       
   407 
       
   408 void CEikServAlarmAlertSession::QueueEventL(TASAltAlertServerResponse& aCode, TAlarmId& aId, TTime& aTimeToSnooze)
       
   409 	{
       
   410 	if (iResponseQueue.Count() < KAlertResponseQueueSize) //ignore new response if queue is full
       
   411 		{
       
   412 		TAlarmResponse response(aCode, aId, aTimeToSnooze);
       
   413 		iResponseQueue.AppendL(response);
       
   414 		}
       
   415 	}
       
   416 
       
   417 
       
   418 void CEikServAlarmAlertSession::ClearAllAlarmsL()
       
   419 	{
       
   420 	RespondEventL(EASAltAlertServerResponseClearAll);
       
   421 	}
       
   422 	
       
   423 
       
   424 void CEikServAlarmAlertSession::SetQuietPeriodL(TTime aQuietPeriodEndTime)
       
   425 	{
       
   426 	iQuietPeriodEndTime = aQuietPeriodEndTime;
       
   427 
       
   428 	RespondEventL(EASAltAlertServerResponseQuietPeriod);
       
   429 	}	
       
   430 
       
   431 
       
   432 TInt CEikServAlarmAlertSession::FindAlarm(TAlarmId aAlarmId) const
       
   433 	{
       
   434 	if (iMaxAlarms == 1)
       
   435 		return 0;
       
   436 
       
   437 	const TInt count = iAlarmSupervisors.Count();
       
   438 	for(TInt i = 0; i < count; i++)
       
   439 		{
       
   440 		if (iAlarmSupervisors[i]->AlarmId() == aAlarmId)
       
   441 			return i;
       
   442 		}
       
   443 		
       
   444 	return KErrNotFound;	
       
   445 	}
       
   446 
       
   447 
       
   448 void CEikServAlarmAlertSession::DeleteAlarmL(const RMessage2& aMessage)
       
   449 	{
       
   450 	if (iMaxAlarms == 1)
       
   451 		{
       
   452 		aMessage.Complete(KErrNone);
       
   453 		return;
       
   454 		}
       
   455 		
       
   456 	TInt idx = 0;
       
   457 	if (aMessage.Function()	== EASAltOpCodeDeleteAlarmAll)		// delete all alarms
       
   458 		{ 
       
   459 		const TInt cnt = iAlarmSupervisors.Count();
       
   460 		for(idx = 0; idx < cnt; idx++)
       
   461 			delete iAlarmSupervisors[idx];
       
   462 
       
   463 		iAlarmSupervisors.Reset();	
       
   464 		aMessage.Complete(KErrNone);
       
   465 		return;	
       
   466 		}
       
   467 	else	//delete particular alarm
       
   468 		{
       
   469 		const TAlarmId alarmId(aMessage.Int0());
       
   470 		if( (idx = FindAlarm(alarmId)) >=0 )	// found!
       
   471 			{
       
   472 			delete iAlarmSupervisors[idx];
       
   473 			iAlarmSupervisors.Remove(idx); 
       
   474 			aMessage.Complete(KErrNone);
       
   475 			}
       
   476 		else	// not found
       
   477 			aMessage.Complete(KErrNotFound);
       
   478 		}	
       
   479 	}
       
   480 	
       
   481 
       
   482 TAlarmResponse::TAlarmResponse(TASAltAlertServerResponse aCode, TAlarmId aId, TTime aTime) :
       
   483 	iCode(aCode),
       
   484 	iId(aId),
       
   485 	iTime(aTime)
       
   486 	{
       
   487 	}
       
   488 
       
   489 
       
   490 TASAltAlertServerResponse TAlarmResponse::ResponseCode() const
       
   491 	{
       
   492 	return iCode;
       
   493 	}
       
   494 
       
   495 
       
   496 TAlarmId TAlarmResponse::AlarmId() const
       
   497 	{
       
   498 	return iId;
       
   499 	}
       
   500 	
       
   501 
       
   502 TTime TAlarmResponse::TimeToSnooze() const
       
   503 	{
       
   504 	return iTime;
       
   505 	}
       
   506