commonappservices/alarmserver/Server/Source/ASSrvSessionEngine.cpp
changeset 0 2e3d3ce01487
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commonappservices/alarmserver/Server/Source/ASSrvSessionEngine.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,691 @@
+// Copyright (c) 1999-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:
+//
+
+#include "ASSrvSessionEngine.h"
+
+// System includes
+
+// User includes
+#include "ASSrvAlarmStore.h"
+#include "ASSrvAlarmQueue.h"
+#include "ASSrvStaticUtils.h"
+#include "ASSrvServerWideData.h"
+#include "ASSrvAnyEventManager.h"
+#include "ASSrvIteratorByState.h"
+#include "ASSrvIteratorByStatus.h"
+#include "ASSrvSessionCollection.h"
+#include "ASSrvIteratorByCategory.h"
+#include "ASSrvIteratorBySessionId.h"
+
+// Type definitions
+
+// Constants
+const TAlarmCategory KCalendarCategeory = {0x101F4A70};
+
+// Enumerations
+
+// Classes referenced
+
+
+//
+// ----> CASSrvSessionEngine (source)
+//
+
+//*************************************************************************************
+CASSrvSessionEngine::CASSrvSessionEngine(CASSrvServerWideData& aServerWideData, MASSrvAnyEventObserver& aChangeObserver, MASSrvSession& aSession)
+:	iServerWideData(aServerWideData), iChangeObserver(aChangeObserver), iSession(aSession)
+	{
+	}
+
+
+//*************************************************************************************
+CASSrvSessionEngine::~CASSrvSessionEngine()
+	{
+	ServerData().SessionCollection().MASSessionCollectionDetach(*this);
+	ServerData().AnyEventManager().MASAnyEventManagerObserverRemove(*this);
+	}
+
+
+//*************************************************************************************
+void CASSrvSessionEngine::ConstructL()
+	{
+	ServerData().AnyEventManager().MASAnyEventManagerObserverAddL(*this);
+	iSessionId = ServerData().SessionCollection().MASSessionCollectionAttachL(*this);
+	}
+
+
+//*************************************************************************************
+CASSrvSessionEngine* CASSrvSessionEngine::NewL(CASSrvServerWideData& aServerWideData, MASSrvAnyEventObserver& aChangeObserver, MASSrvSession& aSession)
+	{
+	CASSrvSessionEngine* self = new(ELeave) CASSrvSessionEngine(aServerWideData, aChangeObserver, aSession);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+//
+//
+//
+
+
+//*************************************************************************************
+/**
+ * @see MASSrvAnyEventObserver
+ *
+ * Facade interface that notifies observer about event. No real processing done
+ * by this object.
+ */
+void CASSrvSessionEngine::MASSrvAnyEventHandleChange(TAlarmChangeEvent aEvent, TAlarmId aAlarmId)
+	{
+	iChangeObserver.MASSrvAnyEventHandleChange(aEvent, aAlarmId);
+	}
+
+
+//
+//
+//
+
+
+//*************************************************************************************
+/**
+ * @see MASSrvSession
+ *
+ * Facade to the real session
+ */
+TASSrvSessionId CASSrvSessionEngine::MASSrvSessionId() const
+	{
+	return iSessionId;
+	}
+
+
+//*************************************************************************************
+/**
+ * @see MASSrvSession
+ *
+ * Facade to the real session
+ */
+void CASSrvSessionEngine::MASSrvSessionFullName(TDes& aDes) const
+	{
+	iSession.MASSrvSessionFullName(aDes);
+	}
+
+
+//
+//
+//
+
+
+//*************************************************************************************
+/**
+ * Add an alarm to the alarm server
+ */
+void CASSrvSessionEngine::AlarmAddL(TASSrvAlarm& aAlarm, TAlarmId aSpecificAlarmId)
+	{
+	// Must clear this - all alarms will have their Id's allocated later
+	aAlarm.Id() = KNullAlarmId;	
+	
+	// clear associateddata, session and state flags
+	aAlarm.ClearFlags();
+
+	// Check the alarm
+	const TInt error = ASSrvStaticUtils::ValidateAlarm(aAlarm);
+	User::LeaveIfError(error);
+
+	// Assign session id
+	aAlarm.SetOriginatingSessionId(MASSrvSessionId());
+
+	// Reset alarm state
+	aAlarm.SetState(EAlarmStateInPreparation);
+
+	// Add the alarm to the queue. This will update the timer if this
+	// new alarm is now the next alarm.
+	ServerData().Queue().QueueAlarmAndAllocateIdL(aAlarm, aSpecificAlarmId);
+	}
+
+
+//*************************************************************************************
+/**
+ * Return information about an alarm
+ */
+void CASSrvSessionEngine::AlarmDetailsL(TAlarmId aAlarmId, TASSrvAlarm& aAlarm) const
+	{
+	// Fetch the alarm details if the specified alarm exists.
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, aAlarm));
+	}
+
+
+//*************************************************************************************
+/**
+ * Delete an alarm from the alarm server
+ */
+void CASSrvSessionEngine::AlarmDeleteL(TAlarmId aAlarmId)
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+
+	// If the alarm has a notification request outstanding against
+	// it, then we don't allow it to be deleted (the only way of
+	// removing the alarm is by cancelling the session notification).
+	if	(alarm.HasNotificationRequestPending())
+		User::Leave(KErrAccessDenied);
+	ServerData().Queue().DeQueueAlarm(alarm);
+	}
+
+
+//*************************************************************************************
+/**
+ * Return the category of a given alarm
+ */
+TAlarmCategory CASSrvSessionEngine::AlarmCategoryL(TAlarmId aAlarmId) const
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+	return alarm.Category();
+	}
+
+
+//*************************************************************************************
+/**
+ * Set the status of an alarm
+ */
+void CASSrvSessionEngine::SetAlarmStatusL(TAlarmId aAlarmId, TAlarmStatus aStatus)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	User::LeaveIfError(alarm.SetStatus(aStatus));
+	}
+
+//*************************************************************************************
+
+void CASSrvSessionEngine::SetAlarmStatusForCalendarFileL(const TDesC& aCalendarFileName, TAlarmStatus aStatus)
+    {
+    CASSrvAlarmQueue& queue = ServerData().Queue();
+    
+    RArray<TAlarmId>* calendarAlarmIds = AlarmIdListByCategoryLC(KCalendarCategeory);
+    const TInt KCalendarAlarmCount(calendarAlarmIds->Count());
+    
+    for (TInt i(0) ; i < KCalendarAlarmCount ; ++i)
+        {
+        TASSrvAlarm* alarm = queue.QueueAlarmById((*calendarAlarmIds)[i]);
+                
+        const TAgnAlarmInfo* alarmInfo = reinterpret_cast<const TAgnAlarmInfo*>(alarm->DataL().Ptr());
+        TBool correctFile = (alarmInfo->iFileName.CompareF(aCalendarFileName) == 0);
+        if(correctFile)
+            {
+            alarm->SetStatus(aStatus);
+            }
+        }
+     CleanupStack::PopAndDestroy(calendarAlarmIds);
+     // coverity[leaked_storage]
+    }
+
+//*************************************************************************************
+/**
+ * Return the status of a given alarm
+ */
+TAlarmStatus CASSrvSessionEngine::AlarmStatusL(TAlarmId aAlarmId) const
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+	return alarm.Status();
+	}
+
+
+//*************************************************************************************
+/**
+ * Set the day/timed status of an alarm
+ */
+void CASSrvSessionEngine::SetAlarmDayOrTimedL(TAlarmId aAlarmId, TAlarmDayOrTimed aDayOrTimed)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	alarm.DayOrTimed() = aDayOrTimed;
+	}
+
+
+//*************************************************************************************
+/**
+ * Return the day/timed status of a given alarm
+ */
+TAlarmDayOrTimed CASSrvSessionEngine::AlarmDayOrTimedL(TAlarmId aAlarmId) const
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+	return alarm.DayOrTimed();
+	}
+
+
+//*************************************************************************************
+/**
+ * Set the characteristics of an alarm
+ */
+void CASSrvSessionEngine::SetAlarmCharacteristicsL(TAlarmId aAlarmId, TAlarmCharacteristicsFlags aCharacteristics)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	alarm.SetCharacteristicsL(aCharacteristics, MASSrvSessionId());
+	}
+
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+void CASSrvSessionEngine::SetWakeupL(TAlarmId aAlarmId, TBool aEnable)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	alarm.SetWakeupAndNotifyQueueL(aEnable);
+	}
+#endif
+
+#ifdef SYMBIAN_ALARM_REPEAT_EXTENSIONS
+void CASSrvSessionEngine::SetAlarmDaysL(TAlarmId aAlarmId, TUint8 aAlarmDays)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	alarm.SetAlarmDaysL(aAlarmDays);
+	}
+
+TUint8 CASSrvSessionEngine::AlarmDaysL(TAlarmId aAlarmId) const
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+	return alarm.AlarmDays();
+	}
+
+void CASSrvSessionEngine::SetContinuousL(TAlarmId aAlarmId, TBool aContinuous)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	alarm.SetContinuous(aContinuous);
+	}
+
+TBool CASSrvSessionEngine::ContinuousL(TAlarmId aAlarmId) const
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+	return alarm.Continuous();
+	}
+
+#endif
+
+void CASSrvSessionEngine::SetAlarmOrphanedL(TAlarmId aAlarmId)
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	TASSrvAlarm& alarm = queue.QueueAlarmByIdL(aAlarmId);
+	alarm.SetAlarmOrphaned();
+	}
+
+
+//*************************************************************************************
+/**
+ * Return the characteristics of an alarm
+ */
+TAlarmCharacteristicsFlags CASSrvSessionEngine::AlarmCharacteristicsL(TAlarmId aAlarmId) const
+	{
+	TASSrvAlarm alarm(ServerData());
+	User::LeaveIfError(ServerData().Queue().QueueAlarmById(aAlarmId, alarm));
+	return alarm.Characteristics();
+	}
+
+
+//
+//
+//
+
+//*************************************************************************************
+void CASSrvSessionEngine::AlarmDataAttachL(TAlarmId aAlarmId, HBufC8* aData)
+	{
+	// Give ownership of the data to the alarm. This will leave with 
+	// KErrInUse should the specified alarm already have attached data.
+	TASSrvAlarm& alarm = ServerData().Queue().QueueAlarmByIdL(aAlarmId);
+	alarm.DataAttachL(aData);
+	}
+
+
+//*************************************************************************************
+void CASSrvSessionEngine::AlarmDataDetachL(TAlarmId aAlarmId)
+	{
+	// Remove the data from the pool - if the specified alarm doesn't exist
+	// within the data pool, then this will leave with KErrNotFound.
+	TASSrvAlarm& alarm = ServerData().Queue().QueueAlarmByIdL(aAlarmId);
+	alarm.DataDetachL();	
+	}
+
+
+
+//*************************************************************************************
+/**
+ * Change all alarms of a given category to have the specified status
+ */
+void CASSrvSessionEngine::SetAlarmStatusByCategoryL(TAlarmCategory aCategory, TAlarmStatus aStatus)
+	{
+	//
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	RASSrvIteratorByCategory iterator(queue, aCategory);
+	iterator.Open();
+	//
+	while(iterator.NextAlarmAvailable())
+		{
+		TASSrvAlarm* alarm = queue.QueueAlarmById(iterator.NextAlarm().Id());
+		User::LeaveIfError(alarm->SetStatus(aStatus));
+		}
+	}
+
+
+//*************************************************************************************
+/**
+ * Return the number of alarms within the alarm server queue that
+ * have the specified category identifier.
+ */
+TInt CASSrvSessionEngine::AlarmCountByCategory(TAlarmCategory aCategory) const
+	{
+	TInt count = 0;
+	//
+	RASSrvIteratorByCategory iterator(ServerData().Queue(), aCategory);
+	iterator.Open();
+	//
+	while(iterator.NextAlarmAvailable())
+		{
+		iterator.NextAlarm();
+		++count;
+		}
+	return count;
+	}
+
+
+//*************************************************************************************
+/**
+ * Return the number of alarms within the alarm server that 
+ * have the specified state.
+ */
+TInt CASSrvSessionEngine::AlarmCountByState(TAlarmState aState) const
+	{
+	TInt count = 0;
+	//
+	RASSrvIteratorByState iterator(ServerData().Queue(), aState);
+	iterator.Open();
+	//
+	while(iterator.NextAlarmAvailable())
+		{
+		iterator.NextAlarm();
+		++count;
+		}
+	return count;
+	}
+
+
+//*************************************************************************************
+/**
+ * Delete all of the alarms within the alarm server queue which
+ * match that of the specified category and alarm's state
+ */
+void CASSrvSessionEngine::DeleteAllAlarmsByCategoryL(TAlarmCategory aCategory, TBool aRestrictToOrphanedAlarms, TDeleteType aWhatToDelete)
+ 	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	RArray<TAlarmId>* alarmToDeleteIds = AlarmIdListByCategoryLC(aCategory);
+	TInt count = alarmToDeleteIds->Count();
+	//
+	for (TInt i=0; i<count; ++i)
+		{
+		const TASSrvAlarm* alarm = queue.QueueAlarmById((*alarmToDeleteIds)[i]);
+		const TBool isOrphanedAndDeletable = aRestrictToOrphanedAlarms && alarm->HasBecomeOrphaned();
+		TBool toDelete=EFalse;
+		if (!aRestrictToOrphanedAlarms || isOrphanedAndDeletable)
+			{
+			if(!aWhatToDelete)
+				toDelete=ETrue;
+			else
+				{
+				switch (alarm->State())
+					{
+					case EAlarmStateInPreparation:
+						{
+						toDelete=ETrue;
+						break;
+						}
+
+					case EAlarmStateQueued:
+						{
+						if (aWhatToDelete&EFuture)
+							{
+							toDelete=ETrue;
+							}
+						break;
+						}
+					case EAlarmStateNotified:
+						{
+						if (aWhatToDelete&EExpired)
+							{
+							toDelete=ETrue;
+							}
+						break;
+						}
+
+					case EAlarmStateSnoozed:
+					case EAlarmStateWaitingToNotify:
+					case EAlarmStateNotifying:
+						{
+						if (aWhatToDelete&EActive)
+							{
+							toDelete=ETrue;
+							}
+						break;
+						}
+
+					default:
+						__ASSERT_DEBUG(EFalse, ASSrvStaticUtils::Fault(ASSrvStaticUtils::EASSrvFaultAlarmStateNotHandled));
+					break;
+					}
+				}
+			 if (toDelete)
+				{
+				queue.DeQueueAlarm(*alarm);
+				}
+			}
+		}
+	alarmToDeleteIds->Close();
+	CleanupStack::PopAndDestroy(alarmToDeleteIds);
+	// coverity [leaked_storage]
+	}
+
+//*************************************************************************************
+/**
+ * Delete all of the alarms within the alarm server queue which
+ * match that of the specified calendar file name and alarm's state
+ */
+void CASSrvSessionEngine::DeleteAllAlarmsByCalendarFileL(const TDesC& aCalendarFileName, TDeleteType aWhatToDelete)
+    {
+    RDebug::Print(_L("CASSrvSessionEngine::DeleteAllAlarmsByCalendarFileL"));
+    
+    CASSrvAlarmQueue& queue = ServerData().Queue();
+    RArray<TAlarmId>* calendarAlarmIds = AlarmIdListByCategoryLC(KCalendarCategeory);
+    const TInt KCalendarAlarmCount(calendarAlarmIds->Count());
+    
+    for (TInt i(0) ; i < KCalendarAlarmCount ; ++i)
+        {
+        const TASSrvAlarm* alarm = queue.QueueAlarmById((*calendarAlarmIds)[i]);
+        TBool correctDeleteType(ETrue);
+        
+        const TAgnAlarmInfo* alarmInfo = reinterpret_cast<const TAgnAlarmInfo*>(alarm->DataL().Ptr());
+        TBool correctFile = (alarmInfo->iFileName.CompareF(aCalendarFileName) == 0);
+                
+        if (aWhatToDelete && correctFile)
+            {
+            switch (alarm->State())
+                {
+                case EAlarmStateInPreparation:
+                    {
+                    correctDeleteType = ETrue;
+                    break;
+                    }
+                case EAlarmStateQueued:
+                    {
+                    correctDeleteType = aWhatToDelete & EFuture;
+                    break;
+                    }
+                case EAlarmStateNotified:
+                    {
+                    correctDeleteType = aWhatToDelete & EExpired;
+                    break;
+                    }
+                case EAlarmStateSnoozed:
+                case EAlarmStateWaitingToNotify:
+                case EAlarmStateNotifying:
+                    {
+                    correctDeleteType = aWhatToDelete & EActive;
+                    break;
+                    }
+                default:
+                    {
+                    __ASSERT_DEBUG(EFalse, ASSrvStaticUtils::Fault(ASSrvStaticUtils::EASSrvFaultAlarmStateNotHandled));
+                    }
+                    break;
+                }
+            }
+        
+         if (correctDeleteType && correctFile)
+            {
+            queue.DeQueueAlarm(*alarm);
+            }
+        }
+    
+    calendarAlarmIds->Close();
+    CleanupStack::PopAndDestroy(calendarAlarmIds);
+    // coverity [leaked_storage]
+    }
+
+
+
+//*************************************************************************************
+/**
+ * Return a list of all alarm categories currently in use within
+ * the alarm server queue.
+ */
+RArray<TAlarmCategory>* CASSrvSessionEngine::AlarmCategoryListLC() const
+	{
+	TLinearOrder<TAlarmCategory> order(ASSrvStaticUtils::CompareCategories);
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	//
+	RArray<TAlarmCategory>* list = new(ELeave) RArray<TAlarmCategory>(4);
+	CleanupStack::PushL(TCleanupItem(ASSrvStaticUtils::CleanupCloseDeleteCategoryArray, list));
+	//
+	const TInt count = queue.QueueAlarmCount();
+	for(TInt i=0; i<count; i++)
+		{
+		// Is this category already present in the list?
+		const TAlarmCategory category(queue.QueueAlarmAt(i).Category());
+		if	(list->FindInOrder(category, order) == KErrNotFound)
+			{
+			// Add this category to the list
+			User::LeaveIfError(list->InsertInOrder(category, order));
+			}
+		}
+	//
+	return list;
+	}
+
+
+//*************************************************************************************
+/**
+ * Return a list of alarm ids for a given category
+ */
+RArray<TAlarmId>* CASSrvSessionEngine::AlarmIdListByCategoryLC(TAlarmCategory aCategory) const
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	RASSrvIteratorByCategory iterator(queue, aCategory);
+	iterator.Open();
+	//coverity[return_alloc_fn]
+	return AlarmIdListFromIteratorLC(iterator);
+	}
+
+
+//*************************************************************************************
+/**
+ * Return a list of alarm ids for a given alarm state
+ */
+RArray<TAlarmId>* CASSrvSessionEngine::AlarmIdListByStateLC(TAlarmState aState) const
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	RASSrvIteratorByState iterator(queue, aState);
+	iterator.Open();
+	//
+	return AlarmIdListFromIteratorLC(iterator);
+	}
+
+
+//*************************************************************************************
+/**
+ * Return all alarm ids currently used within the alarm server
+ * queue.
+ */
+RArray<TAlarmId>* CASSrvSessionEngine::AlarmIdListLC() const
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	RASSrvIteratorBase iterator(queue);
+	iterator.Open();
+	//
+	return AlarmIdListFromIteratorLC(iterator);
+	}
+
+
+//*************************************************************************************
+/**
+ * Return the number of active alarms, that is, enabled, queued or snoozed 
+ * alarms
+ */
+TInt CASSrvSessionEngine::NumberOfActiveAlarmsInQueue() const
+	{
+	CASSrvAlarmQueue& queue = ServerData().Queue();
+	//
+	RASSrvIteratorByStatus status(queue, EAlarmStatusEnabled);
+	status.Open();
+	//
+	RASSrvIteratorByState state(queue, EAlarmStateQueued, EAlarmStateSnoozed);
+	status.IteratorAttach(state);
+	//
+	TInt count = 0;
+	while(status.NextAlarmAvailable())
+		{
+		++count;
+		status.NextAlarm();
+		}
+	return count;
+	}
+
+
+//
+//
+//
+
+
+//*************************************************************************************
+/**
+ * Return a list of alarm ids which is generated by navigating the specified iterator
+ */
+RArray<TAlarmId>* CASSrvSessionEngine::AlarmIdListFromIteratorLC(RASSrvIteratorBase& aIterator) const
+	{
+	RArray<TAlarmId>* list = new(ELeave) RArray<TAlarmId>(4);
+	CleanupStack::PushL(TCleanupItem(ASSrvStaticUtils::CleanupCloseDeleteAlarmIdArray, list));
+	//
+	while(aIterator.NextAlarmAvailable())
+		{
+		const TASShdAlarm& alarm = aIterator.NextAlarm();
+		list->AppendL(alarm.Id());
+		}
+	//
+	return list;
+	}
+
+