diff -r 000000000000 -r 2e3d3ce01487 commonappservices/alarmserver/Server/Source/ASSrvNotifyingAlarmMngr.cpp --- /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(); + }