diff -r 000000000000 -r 2f259fa3e83a commonuisupport/uikon/srvsrc/EIKALSRV.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commonuisupport/uikon/srvsrc/EIKALSRV.CPP Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,506 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Multialarm version of Alert Server +// +// + +/** + @file +*/ + +#include "EIKALSRV.H" + +// System includes + +#include "EIKSRV.PAN" +#include +#include +#include + +// User includes +#include "EIKALSUP.H" +#include "EIKSVFTY.H" +#include "EIKPANIC.H" +#include "EIKSRV.PAN" + + +// Security constants + +const TUint8 KPolicyElementSID = 0; + +const TInt KAlarmServerSid = 0x101f5027; + +const TUint KRangeCount = 6; + +const TInt KEikServAlarmAlertServerRanges[KRangeCount] = + { + EASAltOpCodeNotify, + EASAltOpCodeVisible, + EASAltOpCodeGetUserTime, + EASAltOpCodeStartPlayingSound, + EASAltOpCodeGetEndQuietTime, + EASAltOpCodeLast, + }; + +const TUint8 KElementsIndex[KRangeCount] = + { + CPolicyServer::EAlwaysPass, //Always passing no capability required (Notify, NotifyCancel) + KPolicyElementSID, //Requires SID to be of Alarmserver ie.0x101f5027 (Visible,SetState, SetAlarm, SetDeferTime) + CPolicyServer::EAlwaysPass, //Always passing no capability required (GetUserTime, Logon) + KPolicyElementSID, //Requires SID to be of Alarmserver ie.0x101f5027 (StartPlayingSound, StopPlayingSound, VisibleAll, SetStateAll, StopPlayingSoundAll, DeleteAlarm) + CPolicyServer::EAlwaysPass, //Always passing no capability required (GetEndQuietTime, GetMaxAlarms) + CPolicyServer::ENotSupported, //Not Supported [EASAltOpCodeLast-End] + }; + +const CPolicyServer::TPolicyElement KPolicyElements[] = + { + {_INIT_SECURITY_POLICY_S0(KAlarmServerSid), CPolicyServer::EFailClient} + }; + +const CPolicyServer::TPolicy KEikServAlarmAlertServerPolicy = + { + CPolicyServer::EAlwaysPass, + KRangeCount, + KEikServAlarmAlertServerRanges, + KElementsIndex, + KPolicyElements + }; + + +// +// class CEikServAlarmAlertServer +// + +/** +Constructor. +*/ +CEikServAlarmAlertServer::CEikServAlarmAlertServer(TInt aPriority, MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) : + CPolicyServer(aPriority, KEikServAlarmAlertServerPolicy), + iAlarmControlFactory(aAlarmControlFactory), + iMaxAlarms(aMaxAlarms) + { + __ASSERT_ALWAYS(aMaxAlarms > 0, Panic(EEsPanicAlarmAlert)); + } + +/** +Creates a new Alert Server. When an alarm expires, the Alert Server will request an Alarm Control from +the Alarm Control factory. The number of Alarm Controls at any instance in time will not exceed the specified +maximum limit. + +@param aAlarmControlFactory Pointer to the Alarm Control factory. The Alert Server does not take ownership. +@param aMaxAlarms Maximum number of concurrent Alarm Controls that the Alarm Control factory will be requested to manufacture. +@return Pointer to the Alert Server. +*/ +EXPORT_C CEikServAlarmAlertServer* CEikServAlarmAlertServer::NewL(MEikServAlarmFactory* aAlarmControlFactory, TInt aMaxAlarms) + { + CEikServAlarmAlertServer* server = new (ELeave) CEikServAlarmAlertServer(EActivePriorityIpcEventsHigh, *aAlarmControlFactory, aMaxAlarms); + + CleanupStack::PushL(server); + server->StartL(KAlarmAlertServerName); + CleanupStack::Pop(server); + + return server; + } + + +/** +Creates a new Alert Server. When an alarm expires, the Alert Server will request an Alarm Control from +the Alarm Control factory. There is only one Alarm Control at any instance in time. + +@param aAlarmControlFactory Pointer to the Alarm Control factory. The Alert Server does not take ownership. +@return Pointer to the Alert Server. +*/ +EXPORT_C CEikServAlarmAlertServer* CEikServAlarmAlertServer::NewL(MEikServAlarmFactory* aAlarmControlFactory) + { + return NewL(aAlarmControlFactory, 1); + } + +CEikServAlarmAlertServer::~CEikServAlarmAlertServer() + { + iSession = NULL; + } + +CSession2* CEikServAlarmAlertServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const + { + const TVersion KAlarmAlertServerVersion(KASAltVersionMajor, KASAltVersionMinor, KASAltVersionBuild); + if (iSession) + User::Leave(KErrArgument); // There should only ever be one session with the alarm alert server. + + if (!User::QueryVersionSupported(KAlarmAlertServerVersion, aVersion) || aVersion.iMajor <=2) //Current implementation doesn't support old clients + User::Leave(KErrNotSupported); + + CEikServAlarmAlertSession* const session = CEikServAlarmAlertSession::NewL(iAlarmControlFactory, iMaxAlarms); + const_cast(this)->iSession = session; // iSession does not *own* what it points to + return session; + } + + +EXPORT_C void CEikServAlarmAlertServer::TaskKeyPressedL() + { + if (iSession) + iSession->TaskKeyPressedL(); + } + + +EXPORT_C void CEikServAlarmAlertServer::HandleSwitchOnEvent() + { + if (iSession) + iSession->HandleSwitchOnEvent(); + } + + +EXPORT_C void CEikServAlarmAlertServer::SetQuietPeriodL(TTime aQuietPeriodEndTime) + { + if (iSession) + iSession->SetQuietPeriodL(aQuietPeriodEndTime); + } + + +EXPORT_C void CEikServAlarmAlertServer::ClearAllAlarmsL() + { + if (iSession) + iSession->ClearAllAlarmsL(); + } + + +// +// class CEikServAlarmAlertSession +// + + +CEikServAlarmAlertSession* CEikServAlarmAlertSession::NewL(MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) + { + CEikServAlarmAlertSession* const session = new(ELeave) CEikServAlarmAlertSession(aAlarmControlFactory, aMaxAlarms); + CleanupStack::PushL(session); + session->ConstructL(); + CleanupStack::Pop(session); + return session; + } + + +CEikServAlarmAlertSession::CEikServAlarmAlertSession(MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) : + iVisible(EFalse), iAlarmControlFactory(aAlarmControlFactory), iMaxAlarms(aMaxAlarms) + { + } + + +CEikServAlarmAlertSession::~CEikServAlarmAlertSession() + { + CEikServAlarmAlertServer* const server = AlarmAlertServer(); + if (server) + server->SessionDied(); + + // Delete all the alarm supervisors + const TInt count = iAlarmSupervisors.Count(); + for(TInt i = 0; i < count; i++) + delete iAlarmSupervisors[i]; + + iAlarmSupervisors.Reset(); + iResponseQueue.Reset(); + } + + +void CEikServAlarmAlertSession::ConstructL() + { + if (iMaxAlarms == 1) + { + CEikAlmControlSupervisor* alarmSupervisor = CEikAlmControlSupervisor::NewLC(iAlarmControlFactory, this); + iAlarmSupervisors.AppendL(alarmSupervisor); + CleanupStack::Pop(alarmSupervisor); + } + } + + +void CEikServAlarmAlertSession::TaskKeyPressedL() + { + const TInt count = iAlarmSupervisors.Count(); + for(TInt idx = 0; idx < count; idx++) + { + if (iAlarmSupervisors[idx]->IsVisible()) + iAlarmSupervisors[idx]->CmdTaskAwayFromAlarmL(); + } + } + + +void CEikServAlarmAlertSession::HandleSwitchOnEvent() + { + const TInt count = iAlarmSupervisors.Count(); + for(TInt idx = 0; idx < count; idx++) + iAlarmSupervisors[idx]->SynchronizeCountDownTimer(); + } + + +void CEikServAlarmAlertSession::ServiceL(const RMessage2 &aMessage) + { + TInt idSlot(0); + TInt idx(0); + + const TInt opCode = aMessage.Function(); + switch (opCode) + { + case EASAltOpCodeLogon: //Will be completed automatically when session dies. + break; + + case EASAltOpCodeNotify: + if (!iMessage.IsNull()) // don't accept second pending notification request + { + _LIT(KPanicCategory,"EikSrv-ASAlt"); + aMessage.Panic(KPanicCategory, EEsPanicAlarmAlert); + } + else + { + if (iResponseQueue.Count() == 0) + iMessage = aMessage; + else + { + aMessage.WriteL(0, TPckgC(iResponseQueue[0].AlarmId())); + aMessage.WriteL(1, TPckgC(iResponseQueue[0].TimeToSnooze())); + aMessage.Complete(iResponseQueue[0].ResponseCode()); + iResponseQueue.Remove(0); + } + } + break; + + case EASAltOpCodeNotifyCancel: + if (!iMessage.IsNull()) + { + iMessage.Complete(KErrCancel); + aMessage.Complete(KErrNone); + } + else + aMessage.Complete(KErrNone); + break; + + case EASAltOpCodeSetAlarm: + { + TASShdAlarm alarm; + TPckg pAlarm(alarm); + aMessage.ReadL(0,pAlarm); + + if( (idx = FindAlarm(alarm.Id())) >=0 ) + { + iAlarmSupervisors[idx]->ServiceL(aMessage); + aMessage.Complete(KErrNone); + return; + } + + // alarm was not found + if (iAlarmSupervisors.Count() >= iMaxAlarms) + { + // and no room to create new alarm, return KErrNotFound to client to indikate this + aMessage.Complete(KErrNotFound); + return; + } + + CEikAlmControlSupervisor* alarmSupervisor = CEikAlmControlSupervisor::NewLC(iAlarmControlFactory, this); + iAlarmSupervisors.AppendL(alarmSupervisor); + CleanupStack::Pop(alarmSupervisor); + alarmSupervisor->ServiceL(aMessage); + aMessage.Complete(KErrNone); + } + break; + + case EASAltOpCodeGetMaxAlarms: + aMessage.WriteL(0,TPckgC(iMaxAlarms)); + aMessage.Complete(KErrNone); + break; + + case EASAltOpCodeSetState: + case EASAltOpCodeStartPlayingSound: + case EASAltOpCodeVisible: + idSlot = 1; + //fall through + case EASAltOpCodeStopPlayingSound: + { + const TAlarmId alarmId = (idSlot==0 ? aMessage.Int0() : aMessage.Int1()); + if ((idx = FindAlarm(alarmId)) >=0) + { + iAlarmSupervisors[idx]->ServiceL(aMessage); + aMessage.Complete(KErrNone); + } + else //alarm was not found + aMessage.Complete(KErrNotFound); + } + break; + + case EASAltOpCodeVisibleAll: + case EASAltOpCodeSetStateAll: + case EASAltOpCodeStopPlayingSoundAll: + for(idx = 0; idx < iAlarmSupervisors.Count(); idx++) + iAlarmSupervisors[idx]->ServiceL(aMessage); + + aMessage.Complete(KErrNone); + break; + + case EASAltOpCodeSetDeferTime: + { + iQuietPeriodEndTime = TTime(MAKE_TUINT64(aMessage.Int1(), aMessage.Int0())); + aMessage.Complete(KErrNone); + } + break; + + case EASAltOpCodeGetEndQuietTime: + aMessage.WriteL(0,TPckgC(iQuietPeriodEndTime)); + aMessage.Complete(KErrNone); + break; + + case EASAltOpCodeDeleteAlarmAll: + case EASAltOpCodeDeleteAlarm: + DeleteAlarmL(aMessage); + break; + + default: + aMessage.Complete(KErrNotSupported); + break; + } + + UpdateVisibility(); + } + + +CEikServAlarmAlertServer* CEikServAlarmAlertSession::AlarmAlertServer() const + { + return static_cast( const_cast(Server()) ); + } + + +void CEikServAlarmAlertSession::UpdateVisibility() + { + iVisible = EFalse; + + const TInt count = iAlarmSupervisors.Count(); + for(TInt i = 0; i < count; i++) + iVisible |= iAlarmSupervisors[i]->IsVisible(); + } + + + +void CEikServAlarmAlertSession::RespondEventL(TASAltAlertServerResponse aCode) + { + RespondEventL(aCode, KNullAlarmId); + } + + +void CEikServAlarmAlertSession::RespondEventL(TASAltAlertServerResponse aCode, TAlarmId aId, TTime aTimeToSnooze) + { + if (iMessage.IsNull()) // if no request pending + QueueEventL(aCode, aId, aTimeToSnooze); + else + { + iMessage.WriteL(0,TPckgC(aId)); + iMessage.WriteL(1,TPckgC(aTimeToSnooze)); + iMessage.Complete(aCode); + } + } + + +void CEikServAlarmAlertSession::QueueEventL(TASAltAlertServerResponse& aCode, TAlarmId& aId, TTime& aTimeToSnooze) + { + if (iResponseQueue.Count() < KAlertResponseQueueSize) //ignore new response if queue is full + { + TAlarmResponse response(aCode, aId, aTimeToSnooze); + iResponseQueue.AppendL(response); + } + } + + +void CEikServAlarmAlertSession::ClearAllAlarmsL() + { + RespondEventL(EASAltAlertServerResponseClearAll); + } + + +void CEikServAlarmAlertSession::SetQuietPeriodL(TTime aQuietPeriodEndTime) + { + iQuietPeriodEndTime = aQuietPeriodEndTime; + + RespondEventL(EASAltAlertServerResponseQuietPeriod); + } + + +TInt CEikServAlarmAlertSession::FindAlarm(TAlarmId aAlarmId) const + { + if (iMaxAlarms == 1) + return 0; + + const TInt count = iAlarmSupervisors.Count(); + for(TInt i = 0; i < count; i++) + { + if (iAlarmSupervisors[i]->AlarmId() == aAlarmId) + return i; + } + + return KErrNotFound; + } + + +void CEikServAlarmAlertSession::DeleteAlarmL(const RMessage2& aMessage) + { + if (iMaxAlarms == 1) + { + aMessage.Complete(KErrNone); + return; + } + + TInt idx = 0; + if (aMessage.Function() == EASAltOpCodeDeleteAlarmAll) // delete all alarms + { + const TInt cnt = iAlarmSupervisors.Count(); + for(idx = 0; idx < cnt; idx++) + delete iAlarmSupervisors[idx]; + + iAlarmSupervisors.Reset(); + aMessage.Complete(KErrNone); + return; + } + else //delete particular alarm + { + const TAlarmId alarmId(aMessage.Int0()); + if( (idx = FindAlarm(alarmId)) >=0 ) // found! + { + delete iAlarmSupervisors[idx]; + iAlarmSupervisors.Remove(idx); + aMessage.Complete(KErrNone); + } + else // not found + aMessage.Complete(KErrNotFound); + } + } + + +TAlarmResponse::TAlarmResponse(TASAltAlertServerResponse aCode, TAlarmId aId, TTime aTime) : + iCode(aCode), + iId(aId), + iTime(aTime) + { + } + + +TASAltAlertServerResponse TAlarmResponse::ResponseCode() const + { + return iCode; + } + + +TAlarmId TAlarmResponse::AlarmId() const + { + return iId; + } + + +TTime TAlarmResponse::TimeToSnooze() const + { + return iTime; + } +