diff -r 000000000000 -r f979ecb2b13e pimappservices/calendar/client/src/calsessionimpl.cpp --- /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(*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 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 calFileChangeInfos; + CleanupResetAndDestroyPushL(calFileChangeInfos); + RPointerArray agnFileChangeInfos; + CleanupResetAndDestroyPushL(agnFileChangeInfos); + iAgnServer->GetFileChangesSinceLastNotificationL(agnFileChangeInfos, iSessionId); + const TInt count = agnFileChangeInfos.Count(); + calFileChangeInfos.ReserveL(count); + for(TInt ii=0; ii 0) + { + iFileChangeObserver->CalendarInfoChangeNotificationL(calFileChangeInfos); + } + CleanupStack::PopAndDestroy(&agnFileChangeInfos); + CleanupStack::PopAndDestroy(&calFileChangeInfos); + } + else + { + User::Invariant(); + } + } + +void CCalSessionImpl::EntryHasChangedL(RArray& aChangedEntries) + { + if (iChangeObserver) + { + iChangeObserver->CalChangeNotification(aChangedEntries); + } + + if (iChangeCallBack) + { + TBool includeTodo = EFalse; + TBool includeEvent = EFalse; + TInt count=aChangedEntries.Count(); + TInt ii=0; + while(iiCalChangeNotification(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); + } + } + } +