commonappservices/alarmserver/Server/Source/ASSrvNotifyingAlarmMngr.cpp
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 2005-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 // Implementation of CASSrvNotifyingAlarmMngr
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology
       
    21 */
       
    22 
       
    23 #include "ASSrvNotifyingAlarmMngr.h"
       
    24 #include "ASSrvServerWideData.h"
       
    25 #include "ASSrvTimer.h"
       
    26 #include "ASSrvAlarmQueue.h"
       
    27 #include "ASSrvNotificationCoordinator.h"
       
    28 
       
    29 /**
       
    30 Standard 2 phase constructor
       
    31 */
       
    32 CASSrvNotifyingAlarmMngr* CASSrvNotifyingAlarmMngr::NewL(CASSrvNotificationCoordinator& aParent, CASSrvServerWideData& aServerWideData)
       
    33 	{
       
    34 	CASSrvNotifyingAlarmMngr* self = new (ELeave) CASSrvNotifyingAlarmMngr(aParent, aServerWideData);
       
    35 	CleanupStack::PushL(self);
       
    36 	self->ConstructL();
       
    37 	CleanupStack::Pop(self);
       
    38 	return self;
       
    39 	}
       
    40 
       
    41 /**
       
    42 Destructor
       
    43 */
       
    44 CASSrvNotifyingAlarmMngr::~CASSrvNotifyingAlarmMngr()
       
    45 	{
       
    46 	ServerWideData().Timer().NotifyAlarmExpiredCancel(*this);
       
    47 	iCurrentlyNotifyingAlarmIds.Close();
       
    48 	}
       
    49 
       
    50 /**
       
    51 Standard 2nd phase constractor
       
    52 */
       
    53 void CASSrvNotifyingAlarmMngr::ConstructL()
       
    54 	{
       
    55 	ServerWideData().Timer().NotifyAlarmExpiredL(*this);
       
    56 	}
       
    57 
       
    58 /**
       
    59 Standard private constructor
       
    60 */
       
    61 CASSrvNotifyingAlarmMngr::CASSrvNotifyingAlarmMngr(CASSrvNotificationCoordinator& aParent, CASSrvServerWideData& aServerWideData)
       
    62 :iParent(aParent), iServerWideData(aServerWideData)
       
    63 	{
       
    64 	}
       
    65 
       
    66 /**
       
    67 Set the maximum number of alarms supported by Alert Server
       
    68 */
       
    69 void CASSrvNotifyingAlarmMngr::SetMaxNumberOfAlarms(TInt aMaxAlarms)
       
    70 	{
       
    71 	iMaxNumberOfAlarms = aMaxAlarms;
       
    72 	}
       
    73 
       
    74 /**
       
    75 @see MASSrvAlarmTimerObserver
       
    76 */
       
    77 void CASSrvNotifyingAlarmMngr::MATimerHandleAlarmExpired(TAlarmTimerEvent aEvent, TAlarmId aAlarmId)
       
    78 	{
       
    79 	if (aEvent != EAlarmTimerEventAlarmExpired)
       
    80 		{
       
    81 		return;
       
    82 		}
       
    83 
       
    84 	CASSrvAlarmQueue& queue = ServerWideData().Queue();
       
    85 	TASSrvAlarm* justExpiredAlarm = queue.QueueAlarmById(aAlarmId);
       
    86 
       
    87 	if (SoleNotifyingAlarmHasSoundPaused())
       
    88 	// If there's 1 alarm notifying and it has it's sound paused,
       
    89 		{
       
    90 		// then we'll snooze it and take it's place.
       
    91 		TASSrvAlarm* pausedAlarm = queue.QueueAlarmById(iCurrentlyNotifyingAlarmIds[0]);
       
    92 		pausedAlarm->SetState(EAlarmStateSnoozed);
       
    93 		SetAsNextNotifyingAlarm(aAlarmId);
       
    94 		}
       
    95 	else if (AllowMoreNotifyingAlarms())
       
    96 	// If the number of notifying alarm is less than maximum allowed
       
    97 		{
       
    98 		if (iParent.SetAlarmInProgress())
       
    99 		// Alert server hasn't replied to the previous alarm...
       
   100 			{
       
   101 			// set the alarm state to waiting to notify
       
   102 			justExpiredAlarm->SetState(EAlarmStateWaitingToNotify);
       
   103 			}
       
   104 		else 
       
   105 			{
       
   106 			SetAsNextNotifyingAlarm(aAlarmId);
       
   107 			}
       
   108 		}
       
   109 	else
       
   110 	// The max number of allowed alarm has reached, set the state of the just 
       
   111 	// expired alarm depending on its exipry time
       
   112 		{
       
   113 		TAlarmId youngestAlarmId(YoungestNotifyingAlarmId());
       
   114 		TASSrvAlarm* youngestAlarm = queue.QueueAlarmById(youngestAlarmId);
       
   115 		if	(justExpiredAlarm->OriginalExpiryTime() < youngestAlarm->OriginalExpiryTime() && !justExpiredAlarm->HasSoundPaused())
       
   116 			{
       
   117 			// The alarm that just expired is actually older than an alarm
       
   118 			// we're notifying about. This kind of thing can occur
       
   119 			// when somebody adds an alarm to the alarm server which is 
       
   120 			// in the past, e.g a day in the past, and the alarm server is 
       
   121 			// already notifying about an alarm which is 1 minute old.
       
   122 			//
       
   123 			// In this case, an alarm which we were notifying about should no
       
   124 			// longer in the notifying queue, therefore we set its state back
       
   125 			// to "waiting to notify" and then proceed to notify about this
       
   126 			// new alarm.
       
   127 			youngestAlarm->SetState(EAlarmStateWaitingToNotify);
       
   128 			SetAsNextNotifyingAlarm(aAlarmId);
       
   129 			}
       
   130 		else
       
   131 			{
       
   132 			justExpiredAlarm->SetState(EAlarmStateWaitingToNotify);
       
   133 			}
       
   134 		}
       
   135 	}
       
   136 
       
   137 /**
       
   138 Return the server data object.
       
   139 */
       
   140 CASSrvServerWideData& CASSrvNotifyingAlarmMngr::ServerWideData() const
       
   141 	{
       
   142 	return iServerWideData;
       
   143 	}
       
   144 
       
   145 /**
       
   146 Set the alarm with the given alarm id to be the next notifying alarm
       
   147 @param aAlarmId the id of the alarm to set to notifying state
       
   148 */
       
   149 void CASSrvNotifyingAlarmMngr::SetAsNextNotifyingAlarm(TAlarmId aAlarmId)
       
   150 	{
       
   151 	// This function shouldn't be called if max # of alarm has reached
       
   152 	__ASSERT_DEBUG(AllowMoreNotifyingAlarms(), 
       
   153 		ASSrvStaticUtils::Fault(ASSrvStaticUtils::EASSrvFaultNotifyAlarmExceedMax));
       
   154 
       
   155 	CASSrvAlarmQueue& queue = ServerWideData().Queue();
       
   156 	TASSrvAlarm* alarm = queue.QueueAlarmById(aAlarmId);
       
   157 
       
   158 	// Update the alarm we are notifying about
       
   159 	if (iCurrentlyNotifyingAlarmIds.Append(aAlarmId) != KErrNone)
       
   160 		{
       
   161 		ASSrvStaticUtils::Panic(ASSrvStaticUtils::EASSrvPanicOutOfMemory);
       
   162 		}
       
   163 
       
   164 	// Now we can start notifying this new alarm. Because this class observes all
       
   165 	// state or status changes, we will be notified about the change and will
       
   166 	// update the Alarm Alert Server accordingly.
       
   167 	TAlarmState state(EAlarmStateNotifying);
       
   168 #ifdef _DEBUG
       
   169 	if (iParent.PreventUserNotification())
       
   170 		{
       
   171 		state = EAlarmStateNotified;
       
   172 		// Remove the alarm from notifying list
       
   173 		iCurrentlyNotifyingAlarmIds.Remove(iCurrentlyNotifyingAlarmIds.Count() - 1);
       
   174 		}
       
   175 #endif
       
   176 	alarm->SetState(state);
       
   177 	}
       
   178 
       
   179 TBool CASSrvNotifyingAlarmMngr::AmNotifyingAboutAlarm() const
       
   180 	{
       
   181 	return (iCurrentlyNotifyingAlarmIds.Count() > 0);
       
   182 	}
       
   183 
       
   184 /**
       
   185 Locate and initiate notifications for the next alarm in the queue that is waiting
       
   186 @param aUpdate if true, update alert server if next alarm is not available
       
   187 */
       
   188 void CASSrvNotifyingAlarmMngr::FindAndExecuteNextAlarmAwaitingNotification(TBool aUpdate)
       
   189 	{
       
   190 	if(AllowMoreNotifyingAlarms() && ServerWideData().Queue().HaveAdditionalAlarmsToNotify())
       
   191 		{
       
   192 		TASSrvAlarm& alarm = ServerWideData().Queue().NextAlarmWaitingForNotification();
       
   193 		SetAsNextNotifyingAlarm(alarm.Id());
       
   194 		}
       
   195 	else if (aUpdate && !AmNotifyingAboutAlarm())
       
   196 		{
       
   197 		// Alarm server has no more alarm to notify, so update Alert Server
       
   198 		// visibility and flags
       
   199 		iParent.UpdateAlarmAlertServer(KNullAlarmId);
       
   200 		}
       
   201 	}
       
   202 
       
   203 /**
       
   204 Check if the given alarm is in the alarm notifying list
       
   205 */
       
   206 TBool CASSrvNotifyingAlarmMngr::AlarmIsNotifying(TAlarmId aAlarmId) const
       
   207 	{
       
   208 	if (iCurrentlyNotifyingAlarmIds.Find(aAlarmId) != KErrNotFound)
       
   209 		{
       
   210 		return ETrue;
       
   211 		}
       
   212 	return EFalse;	
       
   213 	}
       
   214 
       
   215 /**
       
   216 Check if alert server can accept more notifying alarm
       
   217 */
       
   218 TBool CASSrvNotifyingAlarmMngr::AllowMoreNotifyingAlarms() const
       
   219 	{
       
   220 	if (iCurrentlyNotifyingAlarmIds.Count() < iMaxNumberOfAlarms)
       
   221 		{
       
   222 		return ETrue;
       
   223 		}
       
   224 	return EFalse;	
       
   225 	}
       
   226 
       
   227 /*
       
   228 Returns the Alarm Id for the "youngest" notifying alarm, ie. with the largest (latest) OriginalExpiryTime.
       
   229 */
       
   230 TAlarmId CASSrvNotifyingAlarmMngr::YoungestNotifyingAlarmId() const
       
   231 	{
       
   232 	// This function shouldn't be called if there are no notifying alarms
       
   233 	__ASSERT_DEBUG(iCurrentlyNotifyingAlarmIds.Count(), 
       
   234 		ASSrvStaticUtils::Fault(ASSrvStaticUtils::EASSrvFaultNoNotifyingAlarms));
       
   235 
       
   236 	CASSrvAlarmQueue& queue = ServerWideData().Queue();
       
   237 
       
   238 	TAlarmId youngestAlarm(iCurrentlyNotifyingAlarmIds[0]);
       
   239 	TTime latestTime(queue.QueueAlarmById(youngestAlarm)->OriginalExpiryTime());
       
   240 
       
   241 	for(TInt i = iCurrentlyNotifyingAlarmIds.Count()-1; i >= 1 ; i--)
       
   242 		{
       
   243 		TASSrvAlarm* currentAlarm = queue.QueueAlarmById(iCurrentlyNotifyingAlarmIds[i]);
       
   244 
       
   245 		if	(latestTime < currentAlarm->OriginalExpiryTime())
       
   246 			{
       
   247 			youngestAlarm = currentAlarm->Id();
       
   248 			latestTime = queue.QueueAlarmById(youngestAlarm)->OriginalExpiryTime();
       
   249 			}
       
   250 		}
       
   251 
       
   252 	return youngestAlarm;
       
   253 	}
       
   254 
       
   255 
       
   256 /*
       
   257 Determine if there is only 1 Notifying Alarm and if has it's Sound Paused.
       
   258 @return ETrue if this is true. Otherwise EFalse
       
   259 */
       
   260 TBool CASSrvNotifyingAlarmMngr::SoleNotifyingAlarmHasSoundPaused() const
       
   261 	{
       
   262 	if( iCurrentlyNotifyingAlarmIds.Count() != 1 )
       
   263 		{
       
   264 		return EFalse;
       
   265 		}
       
   266 
       
   267 	TASSrvAlarm* notifyingAlarm = ServerWideData().Queue().QueueAlarmById(iCurrentlyNotifyingAlarmIds[0]);
       
   268 
       
   269 	if	(notifyingAlarm->HasSoundPaused())
       
   270 		{
       
   271 		return ETrue;
       
   272 		}
       
   273 
       
   274 	return EFalse;
       
   275 	}
       
   276 
       
   277 /**
       
   278 Remove an alarm from the notifying alarm list
       
   279 @param aAlarmId the id of the alarm to be removed
       
   280 @return ETrue if the alarm was in the notifying list before removal. Otherwise EFalse
       
   281 */
       
   282 TBool CASSrvNotifyingAlarmMngr::RemoveNotifyingAlarm(TAlarmId aAlarmId)
       
   283 	{
       
   284 	TInt alarmIndex(iCurrentlyNotifyingAlarmIds.Find(aAlarmId));
       
   285 	if (alarmIndex == KErrNotFound)
       
   286 		{
       
   287 		return EFalse;
       
   288 		}
       
   289 	
       
   290 	iCurrentlyNotifyingAlarmIds.Remove(alarmIndex);
       
   291 	return ETrue;
       
   292 	}
       
   293 
       
   294 /**
       
   295 Remove all alarms from the notifying alarm list
       
   296 */
       
   297 void CASSrvNotifyingAlarmMngr::RemoveAllNotifyingAlarms()
       
   298 	{
       
   299 	iCurrentlyNotifyingAlarmIds.Reset();
       
   300 	}
       
   301 
       
   302 /**
       
   303 Return the number of the notifying alarm
       
   304 */
       
   305 TInt CASSrvNotifyingAlarmMngr::NumberOfNotifyingAlarm()
       
   306 	{
       
   307 	return iCurrentlyNotifyingAlarmIds.Count();
       
   308 	}
       
   309 
       
   310 /**
       
   311 Set all notifying alarm to Notified state
       
   312 */
       
   313 void CASSrvNotifyingAlarmMngr::AcknowledgeAllNotifyingAlarms()
       
   314 	{
       
   315 	CASSrvAlarmQueue& queue = ServerWideData().Queue();
       
   316 
       
   317 	TInt count(iCurrentlyNotifyingAlarmIds.Count());
       
   318 	for (TInt i = 0; i < count; i++)
       
   319 		{
       
   320 		TASSrvAlarm* alarm = queue.QueueAlarmById(iCurrentlyNotifyingAlarmIds[i]);
       
   321 		alarm->SetState(EAlarmStateNotified);
       
   322 		}
       
   323 		
       
   324 	// Because we disabled the AlarmObservers, we have to
       
   325 	// manually remove the alarms
       
   326 	iCurrentlyNotifyingAlarmIds.Reset();
       
   327 	}