pimappservices/calendar/client/src/calsessionimpl.cpp
changeset 0 f979ecb2b13e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendar/client/src/calsessionimpl.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,596 @@
+// 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:
+//
+
+#include "calsessionimpl.h"
+
+#include "calclient.h"
+#include "agmallocator.h"
+#include "agmutil.h"
+#include "calcommonimpl.h"
+#include "calentryimpl.h"
+#include "calinstance.h"
+#include "agmentry.h"
+#include "calcalendarinfo.h"
+#include "calcalendarinfoimpl.h"
+#include "agmcalendarinfo.h"
+#include "calfilechangenotification.h"
+#include "agmfilechangenotification.h"
+
+CCalSessionImpl::CCalSessionImpl()
+	{
+	iFileId = 0;
+	}
+
+void CCalSessionImpl::ConstructL()
+	{
+	iAgnServer = RAgendaServ::NewL();	
+	User::LeaveIfError(iAgnServer->Connect());
+	iAgnChangeReporter = CAgnChangeReporter::NewL(*this);
+	iCalAsyncTaskManager = CCalAsyncTaskManager::NewL(*this);
+	iAgnServer->AddSessionL(*this, iSessionId);
+	}
+
+void CCalSessionImpl::ConstructL(CCalSessionImpl& aCalSessionImpl)
+	{
+	iAgnServer = &aCalSessionImpl.Server();
+	iAgnServer->AddSessionL(*this, iSessionId);
+	iAgnChangeReporter = CAgnChangeReporter::NewL(*this);
+	iCalAsyncTaskManager = CCalAsyncTaskManager::NewL(*this);
+	}
+
+CCalSessionImpl* CCalSessionImpl::NewL()
+	{
+	CCalSessionImpl* self = new (ELeave) CCalSessionImpl();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CCalSessionImpl*  CCalSessionImpl::NewL(CCalSessionImpl& aCalSessionImpl)
+	{
+	CCalSessionImpl* self = new (ELeave) CCalSessionImpl();
+	CleanupStack::PushL(self);
+	self->ConstructL(aCalSessionImpl);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+TInt64 CCalSessionImpl::FileId()
+	{
+	return iFileId;
+	}
+RAgendaServ& CCalSessionImpl::Server() const
+	{
+	return *iAgnServer;
+	}
+
+CCalSessionImpl::~CCalSessionImpl()
+	{
+	__ASSERT_DEBUG(iReferenceCount==0, CalUtils::Panic(ESessionHasOpenReferences));
+	iCallBack = NULL;
+
+	delete iCalAsyncTaskManager;//Have to be deleted first because it will cancel any asyn tesk
+	if(iAgnChangeReporter && iAgnChangeReporter->IsAdded() && iAgnChangeReporter->IsActive())
+		{
+		iAgnChangeReporter->StopReporter();
+		}
+	delete iAgnChangeReporter;
+	if(iSessionId > 0)
+	    {
+	    iAgnServer->CloseAgenda(iSessionId);
+	    }	
+	if (iAgnServer && !iAgnServer->RemoveSession(*this) )
+		{
+		iAgnServer->Close();
+		delete iAgnServer;
+		}	
+	delete iFileName;
+	}
+	
+/**
+@capability ReadUserData
+*/
+CAgnSimpleEntry* CCalSessionImpl::GetSimpleEntryFromServerL(const TAgnInstance& aInstance)
+	{
+	return iAgnServer->GetSimpleEntryL(aInstance.iId, aInstance.iCollectionId);
+	}
+
+CAgnSimpleEntry* CCalSessionImpl::GetSimpleEntryFromServerL(TUint32 aInstance)
+	{
+	return iAgnServer->GetSimpleEntryL(iCollectionId, aInstance);
+	}
+
+
+void CCalSessionImpl::StartChangeNotificationL(MCalChangeCallBack* aCallBack,
+												MCalChangeCallBack::TChangeEntryType aChangeEntryType,
+												TBool aIncludeUndatedTodos,
+												TTime aFilterStartTime,
+												TTime aFilterEndTime)
+	{
+	iChangeCallBack = aCallBack;
+	iAgnChangeReporter->StartReporterL((MCalChangeCallBack2::TChangeEntryType)aChangeEntryType, aIncludeUndatedTodos, aFilterStartTime, aFilterEndTime);
+	}
+	
+void CCalSessionImpl::StartChangeNotificationL(MCalChangeCallBack2& aChangeObserver, const CCalChangeNotificationFilter& aFilter)
+	{
+	iChangeObserver = &aChangeObserver;
+	iAgnChangeReporter->StartReporterL(aFilter.ChangeEntryType(), aFilter.IncludeUndatedTodos(), aFilter.StartTime().TimeUtcL(), aFilter.EndTime().TimeUtcL());
+	}
+
+void CCalSessionImpl::StartFileChangeNotificationL(MCalFileChangeObserver& aCallBack)
+    {
+    iFileChangeObserver = &aCallBack;
+    iAgnChangeReporter->StartFileChangeReporterL();
+    }
+
+void CCalSessionImpl::StopChangeNotification()
+	{
+	iAgnChangeReporter->StopEntryChangeNotification();
+	}
+
+void CCalSessionImpl::StopFileChangeNotification()
+    {
+    iAgnChangeReporter->StopFileChangeNotification();
+    }
+
+void CCalSessionImpl::DisableChangeBroadcast()
+	{
+	iAgnServer->DisableChangeBroadcast(iFileId);
+	}
+
+void CCalSessionImpl::EnableChangeBroadcast()
+	{
+	iAgnServer->EnableChangeBroadcast(iFileId);
+	}
+
+const TDesC& CCalSessionImpl::FileName()
+	{
+	if(iFileName)
+		{
+		return *iFileName;
+		}
+	else
+		{
+		return KNullDesC();
+		}
+	}
+	
+void CCalSessionImpl::OpenL(const TDesC& aFileName, CalCommon::TCalFileVersionSupport& aStatus) const
+	{
+	if(iReferenceCount>0)
+		{
+		User::Leave(KErrInUse);
+		}
+	iAgnServer->OpenAgendaL(*this, aFileName, aStatus, iFileId, iCollectionId);
+	HBufC* newFileName = aFileName.AllocL();
+	delete iFileName;
+	iFileName = newFileName;
+	}
+
+void CCalSessionImpl::IncrementReferenceCount()
+	{
+	++iReferenceCount;
+	}
+
+void CCalSessionImpl::DecrementReferenceCount()
+	{
+	__ASSERT_DEBUG(iReferenceCount>0, User::Invariant());
+	--iReferenceCount;
+	}
+
+void CCalSessionImpl::DeleteCalFileL(const TDesC& aFileName) const
+	{
+	if (aFileName.Length()==0)
+		{
+		User::Leave(KErrArgument);
+		}
+	
+	if(iCalAsyncTaskManager)
+		{
+		iCalAsyncTaskManager->CancelAsynTask();
+		}
+	iAgnChangeReporter->StopEntryChangeNotification();
+	iAgnServer->DeleteAgendaFileL(aFileName, iSessionId);
+	
+	if (iFileName && iFileName->CompareF(aFileName) == 0)
+	    {
+	    // we have deleted the file that we had open
+	    delete iFileName;
+	    iFileName = NULL;
+	    }
+	}
+
+void CCalSessionImpl::CreateCalFileL(const TDesC&  aFileName) const
+	{
+	if (iAgnServer->AgendaFileExistsL(aFileName))
+		{
+		User::Leave(KErrAlreadyExists);
+		}
+	else
+		{
+		TRAPD(err, iAgnServer->CreateAgendaFileL(aFileName));
+		if (err != KErrNone)
+			{
+			TRAP_IGNORE(iAgnServer->DeleteAgendaFileL(aFileName, iSessionId));
+			User::Leave(err);
+			}
+		}
+	}
+
+void CCalSessionImpl::CreateCalFileL(const TDesC& aFileName, const CCalCalendarInfo& aCalendarInfo) const
+    {
+    CreateCalFileL(aFileName);
+    TRAPD(error, SetCalendarInfoL(aFileName, aCalendarInfo));
+    
+    if (error != KErrNone)
+        {
+        // There was a problem setting the meta data
+        // This should be transactional so try to delete the file
+        
+        TRAP_IGNORE(DeleteCalFileL(aFileName));
+        
+        // Now leave with the reason the we could not set the meta data
+        User::Leave(error);
+        }
+    }
+
+void CCalSessionImpl::SetCalendarInfoL(const CCalCalendarInfo& aCalendarInfo) const
+    {
+    // Make sure a file has been opened
+    if (!iFileName)
+        {
+        User::Leave(KErrNotReady);
+        }
+    
+    SetCalendarInfoL(*iFileName, aCalendarInfo);
+    }
+
+void CCalSessionImpl::SetCalendarInfoL(const TDesC& aFileName, const CCalCalendarInfo& aCalendarInfo) const
+    {
+    iAgnServer->SetCalendarInfoL(aFileName, aCalendarInfo.Impl());
+    }
+
+CCalCalendarInfo* CCalSessionImpl::CalendarInfoL() const
+    {
+    // Make sure a file has been opened
+    if (!iFileName)
+        {
+        User::Leave(KErrNotReady);
+        }
+    
+    CCalCalendarInfoImpl* calInfoImpl(iAgnServer->GetCalendarInfoLC(*iFileName, const_cast<CCalSessionImpl&>(*this)));
+    CCalCalendarInfo* info(CCalCalendarInfo::NewL(calInfoImpl));
+    CleanupStack::Pop(calInfoImpl);
+    return info;
+    }
+
+CDesCArray* CCalSessionImpl::ListCalFilesL() const
+	{
+	return iAgnServer->ListAgendaFilesL();
+	}
+
+const TDesC& CCalSessionImpl::DefaultFileNameL() const
+	{
+	return KDefaultSecureAgendaFileName();
+   	}
+	
+void CCalSessionImpl::FileIdL(TCalFileId& aCalFileId) const
+	{
+	aCalFileId = iFileId;
+	}
+	
+void CCalSessionImpl::_DebugSetHeapFailL(RAllocator::TAllocFail aFail, TInt aRate)
+	{
+	iAgnServer->_DebugSetHeapFailL(aFail, aRate);
+	}
+
+TInt CCalSessionImpl::_DebugRequestAllocatedCellsL()
+	{
+	return iAgnServer->_DebugRequestAllocatedCellsL();
+	}
+
+TInt CCalSessionImpl::_DebugRequestAllocatedHeapSizeL()
+	{
+	return iAgnServer->_DebugRequestAllocatedHeapSizeL();
+	}
+
+void CCalSessionImpl::EnablePubSubNotificationsL()
+	{
+	iAgnServer->SetEnablePubSubNotificationsL(ETrue, FileId());
+	}
+	
+void CCalSessionImpl::DisablePubSubNotificationsL()
+	{
+	iAgnServer->SetEnablePubSubNotificationsL(EFalse, FileId());
+	}
+
+void CCalSessionImpl::GetFileNameL(TCalPubSubData aPubSubData, TDes& aFileName)
+	{
+	CDesCArray* fileArray = ListCalFilesL();
+	CleanupStack::PushL(fileArray);
+	
+	if (fileArray)
+		{
+		const TInt KFileArrayCount = fileArray->Count();
+		for (TInt i(0); i < KFileArrayCount; ++i)
+			{
+			TUint32 hashFileName = FoldAndGenerateHashL((*fileArray)[i]);
+			if (hashFileName == aPubSubData.iFileNameHash)
+				{
+				aFileName = (*fileArray)[i];
+				CleanupStack::PopAndDestroy(fileArray);
+				return;
+				}
+			}
+		}
+		
+	CleanupStack::PopAndDestroy(fileArray);
+	}
+	
+TBool CCalSessionImpl::IsFileNameL(TCalPubSubData aPubSubData, const TDesC& aFileName)
+	{
+	return FoldAndGenerateHashL(aFileName) == aPubSubData.iFileNameHash;
+	}
+	
+TBool CCalSessionImpl::IsOpenedFileL(TCalPubSubData aPubSubData)
+	{
+	if(iFileName)
+		{
+		return (FoldAndGenerateHashL(*iFileName) == aPubSubData.iFileNameHash);
+		}
+	else
+		{
+		User::Leave(KErrArgument);
+		}
+	return EFalse;
+	}
+	
+CCalAsyncTaskManager& CCalSessionImpl::AsyncTaskManager()
+	{
+	return *iCalAsyncTaskManager;
+	}
+
+void CCalSessionImpl::ReportChangeL(TInt aChange)
+    {
+    if(aChange == KErrCorrupt || aChange == EEntryChangeInSameFile)
+        {
+        RArray<TCalChangeEntry> changedEntries;
+        CleanupClosePushL(changedEntries);
+        if (aChange == KErrCorrupt)
+            {            
+            TCalChangeEntry change;
+            change.iChangeType = MCalChangeCallBack2::ERestoredFileCanNotBeOpened;
+            changedEntries.AppendL(change);
+            }
+        else
+            {
+            //If it is a restore file notification, the file ID can be different to the current one. Therefore, iFileId should be updated in the situation.
+            iAgnServer->GetChangesSinceLastNotificationL(changedEntries, iCollectionId, iFileId);
+            }
+        EntryHasChangedL(changedEntries);
+        CleanupStack::PopAndDestroy(&changedEntries); // changedEntries.Close()    
+        }
+    else if(aChange == EFileChange)
+        {       
+        RPointerArray<CCalFileChangeInfo> calFileChangeInfos;
+        CleanupResetAndDestroyPushL(calFileChangeInfos);
+        RPointerArray<CAgnFileChangeInfo> agnFileChangeInfos;
+        CleanupResetAndDestroyPushL(agnFileChangeInfos);
+        iAgnServer->GetFileChangesSinceLastNotificationL(agnFileChangeInfos, iSessionId);
+        const TInt count = agnFileChangeInfos.Count();
+        calFileChangeInfos.ReserveL(count);
+        for(TInt ii=0; ii<count; ++ii)
+            {
+            CCalFileChangeInfo* calFileChangeInfo = CCalFileChangeInfo::NewL(agnFileChangeInfos[ii]);
+            calFileChangeInfos.Append(calFileChangeInfo);
+            agnFileChangeInfos[ii] = NULL;//owership is transfered to calFileChangeInfos
+            }
+        if(calFileChangeInfos.Count() > 0)
+            {
+            iFileChangeObserver->CalendarInfoChangeNotificationL(calFileChangeInfos);
+            }
+        CleanupStack::PopAndDestroy(&agnFileChangeInfos);
+        CleanupStack::PopAndDestroy(&calFileChangeInfos);      
+        }
+    else
+        {
+        User::Invariant();
+        }      
+    }
+    
+void CCalSessionImpl::EntryHasChangedL(RArray<TCalChangeEntry>& aChangedEntries)
+    {
+    if (iChangeObserver)
+        {
+        iChangeObserver->CalChangeNotification(aChangedEntries);
+        }
+        
+    if (iChangeCallBack)
+        {
+        TBool includeTodo = EFalse;
+        TBool includeEvent = EFalse;
+        TInt count=aChangedEntries.Count();
+        TInt ii=0;
+        while(ii<count && (includeTodo == EFalse || includeEvent == EFalse))
+            {
+            TCalChangeEntry change = aChangedEntries[ii];
+            if (change.iChangeType == MCalChangeCallBack2::EChangeUndefined)
+                {
+                includeTodo = ETrue;
+                includeEvent = ETrue;
+                }
+            else
+                {
+                if(aChangedEntries[ii].iEntryType == MCalChangeCallBack2::EChangeEntryTodo)
+                    {
+                    includeTodo = ETrue;
+                    }
+                else
+                    {
+                    includeEvent = ETrue;
+                    }
+                }
+            ++ii;
+            }
+        MCalChangeCallBack::TChangeEntryType entryType = MCalChangeCallBack::EChangeEntryAll;
+        if(!includeTodo)
+            {
+            entryType = MCalChangeCallBack::EChangeEntryEvent;
+            }
+        else if (!includeEvent)
+            {
+            entryType = MCalChangeCallBack::EChangeEntryTodo;
+            }
+        iChangeCallBack->CalChangeNotification(entryType);
+        
+        if (aChangedEntries.Count() == 0)
+            {
+            iChangeCallBack = NULL;
+            }
+        }
+    }
+
+TCalCollectionId CCalSessionImpl::CollectionId()
+	{
+	return iCollectionId;
+	}
+
+TInt CCalSessionImpl::SessionId() const
+    {
+    return iSessionId;
+    }
+
+TTime CCalSessionImpl::TzRulesLastModifiedDateL()
+	{
+	return iAgnServer->TzRulesLastModifiedDateL(iFileId);
+	}
+
+void CCalSessionImpl::__dbgClearTzClientCacheL(TBool aRestartCaching)
+	{
+	iAgnServer->__dbgClearTzClientCacheL(aRestartCaching);
+	}
+
+//
+
+/* CAgnChangeReporter*/
+
+CAgnChangeReporter* CAgnChangeReporter::NewL(CCalSessionImpl& aSession)
+	{
+	return new (ELeave) CAgnChangeReporter(aSession);
+	}	
+
+void CAgnChangeReporter::DoCancel()
+	{
+	//Unset both notification flag
+	iChangeIterested =iChangeIterested& ~EEntryChangeInSameFile;
+	iChangeIterested = iChangeIterested& ~EFileChange;
+	}
+	
+CAgnChangeReporter::CAgnChangeReporter(CCalSessionImpl& aSession) 
+:CActive(EPriorityStandard),iSession(aSession),iChangeIterested(0)
+	{
+	}
+
+CAgnChangeReporter::~CAgnChangeReporter()
+	{
+	StopReporter();
+	}
+
+
+void CAgnChangeReporter::StartReporterL(MCalChangeCallBack2::TChangeEntryType aEntryType,	TBool aIncludeUndatedTodos,	TTime aFilterStartTimeUtc, TTime aFilterEndTimeUtc)
+	{
+	iChangeIterested = iChangeIterested|EEntryChangeInSameFile;
+
+	if (!IsAdded())
+		{
+		CActiveScheduler::Add(this);
+		iStatus = KRequestPending;
+		}
+	iSession.Server().SetChangeNotificationParametersL(aEntryType, aIncludeUndatedTodos, aFilterStartTimeUtc, aFilterEndTimeUtc, iSession.FileId());
+	if (!IsActive())
+		{
+		SetActive();
+		}
+	iSession.Server().RequestChangeNotification(iStatus, iSession.SessionId(), iChangeIterested);
+	}
+
+void CAgnChangeReporter::StartFileChangeReporterL()
+    {
+    iChangeIterested = iChangeIterested|EFileChange;
+    if (!IsAdded())
+        {
+        CActiveScheduler::Add(this);
+        iStatus = KRequestPending;
+        }
+    if (!IsActive())
+        {
+        SetActive();       
+        }
+    iSession.Server().RequestChangeNotification(iStatus, iSession.SessionId(), iChangeIterested);
+    }
+
+void CAgnChangeReporter::StopReporter()
+	{
+	TCalFileId fileid = iSession.FileId();
+	if(fileid > KNullFileId || iChangeIterested &EFileChange)
+		{
+		iSession.Server().CancelChangeNotification(iSession.SessionId(), iChangeIterested);	
+		}
+	Cancel();
+	}
+
+void CAgnChangeReporter::StopEntryChangeNotification()
+    {
+    if(!(iChangeIterested &EFileChange))
+        {
+        StopReporter();       
+        }
+    else
+        {       
+        iSession.Server().CancelChangeNotification(iSession.SessionId(),EEntryChangeInSameFile); 
+        iChangeIterested =iChangeIterested& ~EEntryChangeInSameFile;
+        }
+    }
+
+void CAgnChangeReporter::StopFileChangeNotification()
+    {
+     if(!(iChangeIterested &EEntryChangeInSameFile))
+        {
+        StopReporter();       
+        }
+    else
+        {       
+        iSession.Server().CancelChangeNotification(iSession.SessionId(),EFileChange); 
+        iChangeIterested = iChangeIterested& ~EFileChange;
+        }
+    }
+
+void CAgnChangeReporter::RunL()
+	{
+	if (IsAdded() && (iStatus != KErrCancel))
+		{
+		iSession.ReportChangeL(iStatus.Int());
+
+		// Request another change notification.
+		//
+		if (!IsActive() && iStatus.Int()!=KErrCorrupt)
+			{
+			SetActive();
+			iSession.Server().RequestChangeNotification(iStatus, iSession.SessionId(), iChangeIterested);
+			}
+		}
+	}
+