pimprotocols/pbap/server/pbapfoldernodech.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimprotocols/pbap/server/pbapfoldernodech.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,429 @@
+// Copyright (c) 2006-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 "pbapfoldernodech.h"
+#include "pbapfolderclient.h"
+#include "pbaperrorreporter.h"
+#include "pbapappheader.h"
+#include "pbapserver.h"
+#include "pbapchview.h"
+#include "pbapchexporter.h"
+
+#include "btaccesshostlog.h"
+
+
+// constants
+_LIT(KFolderIch, "ich");
+_LIT(KFolderOch, "och");
+_LIT(KFolderMch, "mch");
+_LIT(KFolderCch, "cch");
+
+
+CFolderNodeCallHistory::CFolderNodeCallHistory(MVirtualFolderClient& aClient, const TDesC& aFolderName, THistoryType aHistoryType)
+: CFolderNode(aClient, aFolderName), iHistoryType(aHistoryType), iPendingExport(ENoExport)
+	{
+	LOG_FUNC
+	}
+
+// must be called by any class that inherits from CFolderNodeCallHistory
+void CFolderNodeCallHistory::ConstructL()
+	{
+	LOG_FUNC
+	
+	// create the view for this folder node
+	iFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogNullFlags);	
+	}
+	
+CFolderNodeCallHistory::~CFolderNodeCallHistory()
+	{
+	LOG_FUNC
+	
+	delete iAsyncExporter;
+	delete iFolderView;
+	delete iReadFolderView;
+ 	}
+
+
+void CFolderNodeCallHistory::CancelGet()
+	{
+	LOG_FUNC
+ 	
+	// cancel any asynchronous export operations and avoid iAsyncExporter is deleted
+	// by itself
+	CPbapChExporter* tmpExporter = iAsyncExporter;
+	iAsyncExporter = NULL;
+	delete tmpExporter;
+	
+	delete iAppHeader;
+	iAppHeader = NULL;		
+	}
+
+void CFolderNodeCallHistory::GetComplete()
+	{
+	LOG_FUNC
+	
+	if (iAsyncExporter)
+		{
+		delete iAsyncExporter;
+		iAsyncExporter = NULL;
+		}
+	}
+
+TInt CFolderNodeCallHistory::DoExport(TExportType aExportType, TInt aHandle)
+	{
+	LOG_FUNC
+	
+	if(iAsyncExporter)
+		{
+		__ASSERT_DEBUG(EFalse, Panic(EVirtualFolderChExportAlreadyExists));
+		return KErrAlreadyExists;
+		}
+	
+
+	TInt err = KErrNone;
+		
+	if ((aExportType == EExportItem) && (iCallHistoryChanged))
+		{
+		// the Call History db has been modified since the last get request
+		// report precondition failed error to obex until next listing
+		// request completes (or new Pbap session initiated)
+		iClient.ErrorReporter().SendPreconditionFailedError();
+		// error already reported above so don't update error
+
+		delete iAppHeader;
+		iAppHeader = NULL;
+		}
+	else if (iReadyToExport)
+		{
+		err = StartExport(aExportType, aHandle);
+		}
+	else
+		{
+		// views not ready, setup a pending export until they are
+		if(iPendingExport != ENoExport)
+			{
+			__ASSERT_DEBUG(EFalse, Panic(EVirtualFolderExportAlreadyPending));
+			return KErrAlreadyExists;
+			}
+
+		if (!iFolderView)
+			{
+			// creating the folder view failed before, try again
+			TRAP(err, iFolderView = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogNullFlags));
+			}
+		
+		// setup this export as pending until we are ready to export
+		if (err == KErrNone)
+			{
+			iPendingExport = aExportType;
+			iPendingHandle = aHandle;
+			}
+		}
+	return err;	
+	}
+
+TInt CFolderNodeCallHistory::DoGetItem(TInt aHandle)
+	{
+	LOG_FUNC
+	return DoExport(EExportItem, aHandle);
+	}
+	
+TInt CFolderNodeCallHistory::DoGetListing()
+	{
+	LOG_FUNC
+	return DoExport(EExportListing);
+	}
+
+TInt CFolderNodeCallHistory::DoGetCount()
+	{
+	LOG_FUNC
+	return DoExport(EExportCount);
+	}
+
+TInt CFolderNodeCallHistory::DoGetFolder()
+	{
+	LOG_FUNC
+	return DoExport(EExportFolder);
+	}
+
+ void CFolderNodeCallHistory::HandleExportComplete(TInt aError)
+ 	{
+ 	LOG_FUNC
+ 		
+ 	if (aError == KErrNotFound && iAppHeader->Operation() == EPullVCard)
+ 		{
+ 		// must report not found to client if attempting to pull a vCard which
+ 		// doesnot exist
+ 		iClient.ErrorReporter().SendNotFoundError();
+ 		}
+ 	else if (aError && iCallHistoryChanged)
+ 		{
+ 		iClient.ErrorReporter().SendPreconditionFailedError();
+ 		}
+ 	else if (aError)
+ 		{
+ 		// error occured during export report service unavailable error to obex 
+ 		iClient.ErrorReporter().SendServiceUnavailableError();
+ 		}
+ 
+  	// a successful listing request allows the ch entries to be pulled again
+ 	// after the database has been modified
+ 	if (aError == KErrNone && iAppHeader->Operation() == EPullVCardListing)
+ 		{
+ 		iCallHistoryChanged = EFalse;
+ 		}
+	
+	delete iAppHeader;
+	iAppHeader = NULL;
+ 	}
+
+
+void CFolderNodeCallHistory::CancelPendingExport(TInt err)
+	{
+	LOG_FUNC
+
+	if (iPendingExport != ENoExport)
+		{
+		// complete the export with an error
+		HandleExportComplete(err);
+		
+		// pending export done
+		iPendingExport = ENoExport;
+		}
+	}
+
+TInt CFolderNodeCallHistory::StartExport(TExportType aExportType, TInt aHandle)
+	{
+	LOG_FUNC
+	
+	if(iAsyncExporter)
+		{
+		__ASSERT_DEBUG(EFalse, Panic(EVirtualFolderChExportAlreadyExists));
+		return KErrAlreadyExists;
+		}
+	if(iReadyToExport == EFalse)
+		{
+		__ASSERT_DEBUG(EFalse, Panic(EVirtualFolderNotReadyToExport));
+		return KErrNotReady;
+		}
+	if(!iFolderView)
+		{
+		__ASSERT_DEBUG(EFalse, Panic(EVirtualFolderIncompleteViews));
+		return KErrNotFound;
+		}
+	
+	TInt err = KErrNone;
+	
+	switch(aExportType)
+		{
+		case EExportItem:
+			// aHandle is decremented here as the PBAP handles for call histories start at 1 and our event index starts at 0
+			TRAP(err, iAsyncExporter = CPbapChSingleItemExporter::NewL(iClient, *this, *iFolderView, aHandle - 1, iAppHeader->VCardVersion(), iAppHeader->Filter()));			
+			break;
+
+		case EExportListing:
+			TRAP(err, iAsyncExporter = CPbapChListingExporter::NewL(iClient, *this, *iFolderView, iReadFolderView, iAppHeader->ListStartOffset(), iAppHeader->MaxListCount()));
+			break;
+		
+		case EExportCount:
+			TRAP(err, iAsyncExporter = CPbapChCountExporter::NewL(iClient, *this, *iFolderView, iReadFolderView));
+			break;
+			
+		case EExportFolder:
+			TRAP(err, iAsyncExporter = CPbapChItemExporter::NewL(iClient, *this, *iFolderView, iReadFolderView, iAppHeader->ListStartOffset(), iAppHeader->MaxListCount(), iAppHeader->VCardVersion(), iAppHeader->Filter()));
+			break;
+			
+		case ENoExport:
+			// nothing to do
+			break;
+		default:
+			break;			
+		}
+	return err;
+	}
+	
+// From MPbapChViewObserver.
+void CFolderNodeCallHistory::CallHistoryViewReady(TInt aError)
+	{
+	LOG_FUNC
+
+	if(aError != KErrNone)
+		{
+		__ASSERT_DEBUG(EFalse, Panic(EVirtualFolderIncompleteViews));
+		}
+
+	// assume we are ready to export unless we determine otherwise
+	iReadyToExport = ETrue;
+	
+	// make sure that we have all the view required to be able to export
+	if ((aError == KErrNone) && (iHistoryType == EMissed) && (!iReadFolderView))
+		{
+		// create view of read missed events, used to determine the number of unread events
+		TRAP(aError, iReadFolderView  = CPbapChView::NewL(iClient.LogClient(), iHistoryType, *this, KLogEventRead));
+
+		if (aError == KErrNone)
+			{
+			// we will be notified again when the read missed events view is ready so wait for
+			// that notification before we are ready to export
+			iReadyToExport = EFalse;
+			}
+		else
+			{
+			// log error but still allow exports to take place, they will just not include the
+			// new unread event count in any export
+			LOG1(_L("Failed to create read missed call view, error: %d"), aError);
+			}
+		}
+	else if (aError != KErrNone)
+		{
+		if (iReadFolderView)
+			{
+			// log error but still allow exports to take place, they will just not include the
+			// new unread event count in any export
+			LOG1(_L("Failed to create read missed call view, error: %d"), aError);
+			
+			delete iReadFolderView;
+			iReadFolderView = NULL;
+			}
+		else
+			{
+			// log error and attempt to create views again on next export
+			LOG1(_L("Failed to create folder call history view, error: %d"), aError);
+			
+			delete iFolderView;
+			iFolderView = NULL;
+
+			iReadyToExport = EFalse;
+			CancelPendingExport(aError);
+			}
+		}
+		
+	// check for any pending exports
+	if ((iReadyToExport) && (iPendingExport != ENoExport))
+		{
+		aError = StartExport(iPendingExport, iPendingHandle);
+		
+		if (aError != KErrNone)
+			{
+			// complete the export with an error
+			HandleExportComplete(aError);
+			}
+	
+		// pending export done
+		iPendingExport = ENoExport;
+		}
+	}
+	
+void CFolderNodeCallHistory::CallHistoryChangeNotification(TBool aViewReady)
+	{
+	LOG_FUNC
+	
+	// Force the PCE to issue a PullvCardListing before we will respond to another
+	// PullvCardEntry request for this folder
+	iCallHistoryChanged = ETrue;
+
+	// check to see if there is an export in progress
+	if (iAsyncExporter)
+		{
+		// cancel the export and report error according to the error reporting
+		// scheme for modified/deleted handles
+		CancelGet();
+		}
+	
+	// the view may need refreshing after a change and therefore we are ready to 
+	// export if the view is ready to use. If not, then we will get notification
+	// via the CallHistoryViewReady callback
+	iReadyToExport = aViewReady;
+	}
+
+
+//
+// CFolderNodeIch
+//
+/*static*/ CFolderNodeIch* CFolderNodeIch::NewL(MVirtualFolderClient& aClient)
+	{
+	LOG_STATIC_FUNC
+	CFolderNodeIch* self = new (ELeave) CFolderNodeIch(aClient);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFolderNodeIch::CFolderNodeIch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderIch(), EIncoming)
+	{
+	LOG_FUNC
+	}	
+	
+	
+//
+// CFolderNodeOch
+//
+/*static*/ CFolderNodeOch* CFolderNodeOch::NewL(MVirtualFolderClient& aClient)
+	{
+	LOG_STATIC_FUNC
+	CFolderNodeOch* self = new (ELeave) CFolderNodeOch(aClient);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFolderNodeOch::CFolderNodeOch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderOch(), EOutgoing)
+	{
+	LOG_FUNC
+	}
+	
+	
+//
+// CFolderNodeMch
+//
+/*static*/ CFolderNodeMch* CFolderNodeMch::NewL(MVirtualFolderClient& aClient)
+	{
+	LOG_STATIC_FUNC
+	CFolderNodeMch* self = new (ELeave) CFolderNodeMch(aClient);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFolderNodeMch::CFolderNodeMch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderMch(), EMissed)
+	{
+	LOG_FUNC
+	}
+	
+			
+//
+// CFolderNodeCch
+//
+/*static*/ CFolderNodeCch* CFolderNodeCch::NewL(MVirtualFolderClient& aClient)
+	{
+	LOG_STATIC_FUNC
+	CFolderNodeCch* self = new (ELeave) CFolderNodeCch(aClient);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFolderNodeCch::CFolderNodeCch(MVirtualFolderClient& aClient)
+: CFolderNodeCallHistory(aClient, KFolderCch(), ECombined)
+	{
+	LOG_FUNC
+	}