--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commonappservices/alarmserver/Server/Source/ASSrvNotifyingAlarmMngr.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,327 @@
+// Copyright (c) 2005-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:
+// Implementation of CASSrvNotifyingAlarmMngr
+//
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include "ASSrvNotifyingAlarmMngr.h"
+#include "ASSrvServerWideData.h"
+#include "ASSrvTimer.h"
+#include "ASSrvAlarmQueue.h"
+#include "ASSrvNotificationCoordinator.h"
+
+/**
+Standard 2 phase constructor
+*/
+CASSrvNotifyingAlarmMngr* CASSrvNotifyingAlarmMngr::NewL(CASSrvNotificationCoordinator& aParent, CASSrvServerWideData& aServerWideData)
+ {
+ CASSrvNotifyingAlarmMngr* self = new (ELeave) CASSrvNotifyingAlarmMngr(aParent, aServerWideData);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Destructor
+*/
+CASSrvNotifyingAlarmMngr::~CASSrvNotifyingAlarmMngr()
+ {
+ ServerWideData().Timer().NotifyAlarmExpiredCancel(*this);
+ iCurrentlyNotifyingAlarmIds.Close();
+ }
+
+/**
+Standard 2nd phase constractor
+*/
+void CASSrvNotifyingAlarmMngr::ConstructL()
+ {
+ ServerWideData().Timer().NotifyAlarmExpiredL(*this);
+ }
+
+/**
+Standard private constructor
+*/
+CASSrvNotifyingAlarmMngr::CASSrvNotifyingAlarmMngr(CASSrvNotificationCoordinator& aParent, CASSrvServerWideData& aServerWideData)
+:iParent(aParent), iServerWideData(aServerWideData)
+ {
+ }
+
+/**
+Set the maximum number of alarms supported by Alert Server
+*/
+void CASSrvNotifyingAlarmMngr::SetMaxNumberOfAlarms(TInt aMaxAlarms)
+ {
+ iMaxNumberOfAlarms = aMaxAlarms;
+ }
+
+/**
+@see MASSrvAlarmTimerObserver
+*/
+void CASSrvNotifyingAlarmMngr::MATimerHandleAlarmExpired(TAlarmTimerEvent aEvent, TAlarmId aAlarmId)
+ {
+ if (aEvent != EAlarmTimerEventAlarmExpired)
+ {
+ return;
+ }
+
+ CASSrvAlarmQueue& queue = ServerWideData().Queue();
+ TASSrvAlarm* justExpiredAlarm = queue.QueueAlarmById(aAlarmId);
+
+ if (SoleNotifyingAlarmHasSoundPaused())
+ // If there's 1 alarm notifying and it has it's sound paused,
+ {
+ // then we'll snooze it and take it's place.
+ TASSrvAlarm* pausedAlarm = queue.QueueAlarmById(iCurrentlyNotifyingAlarmIds[0]);
+ pausedAlarm->SetState(EAlarmStateSnoozed);
+ SetAsNextNotifyingAlarm(aAlarmId);
+ }
+ else if (AllowMoreNotifyingAlarms())
+ // If the number of notifying alarm is less than maximum allowed
+ {
+ if (iParent.SetAlarmInProgress())
+ // Alert server hasn't replied to the previous alarm...
+ {
+ // set the alarm state to waiting to notify
+ justExpiredAlarm->SetState(EAlarmStateWaitingToNotify);
+ }
+ else
+ {
+ SetAsNextNotifyingAlarm(aAlarmId);
+ }
+ }
+ else
+ // The max number of allowed alarm has reached, set the state of the just
+ // expired alarm depending on its exipry time
+ {
+ TAlarmId youngestAlarmId(YoungestNotifyingAlarmId());
+ TASSrvAlarm* youngestAlarm = queue.QueueAlarmById(youngestAlarmId);
+ if (justExpiredAlarm->OriginalExpiryTime() < youngestAlarm->OriginalExpiryTime() && !justExpiredAlarm->HasSoundPaused())
+ {
+ // The alarm that just expired is actually older than an alarm
+ // we're notifying about. This kind of thing can occur
+ // when somebody adds an alarm to the alarm server which is
+ // in the past, e.g a day in the past, and the alarm server is
+ // already notifying about an alarm which is 1 minute old.
+ //
+ // In this case, an alarm which we were notifying about should no
+ // longer in the notifying queue, therefore we set its state back
+ // to "waiting to notify" and then proceed to notify about this
+ // new alarm.
+ youngestAlarm->SetState(EAlarmStateWaitingToNotify);
+ SetAsNextNotifyingAlarm(aAlarmId);
+ }
+ else
+ {
+ justExpiredAlarm->SetState(EAlarmStateWaitingToNotify);
+ }
+ }
+ }
+
+/**
+Return the server data object.
+*/
+CASSrvServerWideData& CASSrvNotifyingAlarmMngr::ServerWideData() const
+ {
+ return iServerWideData;
+ }
+
+/**
+Set the alarm with the given alarm id to be the next notifying alarm
+@param aAlarmId the id of the alarm to set to notifying state
+*/
+void CASSrvNotifyingAlarmMngr::SetAsNextNotifyingAlarm(TAlarmId aAlarmId)
+ {
+ // This function shouldn't be called if max # of alarm has reached
+ __ASSERT_DEBUG(AllowMoreNotifyingAlarms(),
+ ASSrvStaticUtils::Fault(ASSrvStaticUtils::EASSrvFaultNotifyAlarmExceedMax));
+
+ CASSrvAlarmQueue& queue = ServerWideData().Queue();
+ TASSrvAlarm* alarm = queue.QueueAlarmById(aAlarmId);
+
+ // Update the alarm we are notifying about
+ if (iCurrentlyNotifyingAlarmIds.Append(aAlarmId) != KErrNone)
+ {
+ ASSrvStaticUtils::Panic(ASSrvStaticUtils::EASSrvPanicOutOfMemory);
+ }
+
+ // Now we can start notifying this new alarm. Because this class observes all
+ // state or status changes, we will be notified about the change and will
+ // update the Alarm Alert Server accordingly.
+ TAlarmState state(EAlarmStateNotifying);
+#ifdef _DEBUG
+ if (iParent.PreventUserNotification())
+ {
+ state = EAlarmStateNotified;
+ // Remove the alarm from notifying list
+ iCurrentlyNotifyingAlarmIds.Remove(iCurrentlyNotifyingAlarmIds.Count() - 1);
+ }
+#endif
+ alarm->SetState(state);
+ }
+
+TBool CASSrvNotifyingAlarmMngr::AmNotifyingAboutAlarm() const
+ {
+ return (iCurrentlyNotifyingAlarmIds.Count() > 0);
+ }
+
+/**
+Locate and initiate notifications for the next alarm in the queue that is waiting
+@param aUpdate if true, update alert server if next alarm is not available
+*/
+void CASSrvNotifyingAlarmMngr::FindAndExecuteNextAlarmAwaitingNotification(TBool aUpdate)
+ {
+ if(AllowMoreNotifyingAlarms() && ServerWideData().Queue().HaveAdditionalAlarmsToNotify())
+ {
+ TASSrvAlarm& alarm = ServerWideData().Queue().NextAlarmWaitingForNotification();
+ SetAsNextNotifyingAlarm(alarm.Id());
+ }
+ else if (aUpdate && !AmNotifyingAboutAlarm())
+ {
+ // Alarm server has no more alarm to notify, so update Alert Server
+ // visibility and flags
+ iParent.UpdateAlarmAlertServer(KNullAlarmId);
+ }
+ }
+
+/**
+Check if the given alarm is in the alarm notifying list
+*/
+TBool CASSrvNotifyingAlarmMngr::AlarmIsNotifying(TAlarmId aAlarmId) const
+ {
+ if (iCurrentlyNotifyingAlarmIds.Find(aAlarmId) != KErrNotFound)
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+/**
+Check if alert server can accept more notifying alarm
+*/
+TBool CASSrvNotifyingAlarmMngr::AllowMoreNotifyingAlarms() const
+ {
+ if (iCurrentlyNotifyingAlarmIds.Count() < iMaxNumberOfAlarms)
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+/*
+Returns the Alarm Id for the "youngest" notifying alarm, ie. with the largest (latest) OriginalExpiryTime.
+*/
+TAlarmId CASSrvNotifyingAlarmMngr::YoungestNotifyingAlarmId() const
+ {
+ // This function shouldn't be called if there are no notifying alarms
+ __ASSERT_DEBUG(iCurrentlyNotifyingAlarmIds.Count(),
+ ASSrvStaticUtils::Fault(ASSrvStaticUtils::EASSrvFaultNoNotifyingAlarms));
+
+ CASSrvAlarmQueue& queue = ServerWideData().Queue();
+
+ TAlarmId youngestAlarm(iCurrentlyNotifyingAlarmIds[0]);
+ TTime latestTime(queue.QueueAlarmById(youngestAlarm)->OriginalExpiryTime());
+
+ for(TInt i = iCurrentlyNotifyingAlarmIds.Count()-1; i >= 1 ; i--)
+ {
+ TASSrvAlarm* currentAlarm = queue.QueueAlarmById(iCurrentlyNotifyingAlarmIds[i]);
+
+ if (latestTime < currentAlarm->OriginalExpiryTime())
+ {
+ youngestAlarm = currentAlarm->Id();
+ latestTime = queue.QueueAlarmById(youngestAlarm)->OriginalExpiryTime();
+ }
+ }
+
+ return youngestAlarm;
+ }
+
+
+/*
+Determine if there is only 1 Notifying Alarm and if has it's Sound Paused.
+@return ETrue if this is true. Otherwise EFalse
+*/
+TBool CASSrvNotifyingAlarmMngr::SoleNotifyingAlarmHasSoundPaused() const
+ {
+ if( iCurrentlyNotifyingAlarmIds.Count() != 1 )
+ {
+ return EFalse;
+ }
+
+ TASSrvAlarm* notifyingAlarm = ServerWideData().Queue().QueueAlarmById(iCurrentlyNotifyingAlarmIds[0]);
+
+ if (notifyingAlarm->HasSoundPaused())
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+/**
+Remove an alarm from the notifying alarm list
+@param aAlarmId the id of the alarm to be removed
+@return ETrue if the alarm was in the notifying list before removal. Otherwise EFalse
+*/
+TBool CASSrvNotifyingAlarmMngr::RemoveNotifyingAlarm(TAlarmId aAlarmId)
+ {
+ TInt alarmIndex(iCurrentlyNotifyingAlarmIds.Find(aAlarmId));
+ if (alarmIndex == KErrNotFound)
+ {
+ return EFalse;
+ }
+
+ iCurrentlyNotifyingAlarmIds.Remove(alarmIndex);
+ return ETrue;
+ }
+
+/**
+Remove all alarms from the notifying alarm list
+*/
+void CASSrvNotifyingAlarmMngr::RemoveAllNotifyingAlarms()
+ {
+ iCurrentlyNotifyingAlarmIds.Reset();
+ }
+
+/**
+Return the number of the notifying alarm
+*/
+TInt CASSrvNotifyingAlarmMngr::NumberOfNotifyingAlarm()
+ {
+ return iCurrentlyNotifyingAlarmIds.Count();
+ }
+
+/**
+Set all notifying alarm to Notified state
+*/
+void CASSrvNotifyingAlarmMngr::AcknowledgeAllNotifyingAlarms()
+ {
+ CASSrvAlarmQueue& queue = ServerWideData().Queue();
+
+ TInt count(iCurrentlyNotifyingAlarmIds.Count());
+ for (TInt i = 0; i < count; i++)
+ {
+ TASSrvAlarm* alarm = queue.QueueAlarmById(iCurrentlyNotifyingAlarmIds[i]);
+ alarm->SetState(EAlarmStateNotified);
+ }
+
+ // Because we disabled the AlarmObservers, we have to
+ // manually remove the alarms
+ iCurrentlyNotifyingAlarmIds.Reset();
+ }