--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/serviceproviders/sapi_contacts_vpbk/contactservice/src/contactservice.cpp Fri Jul 03 15:51:24 2009 +0100
@@ -0,0 +1,639 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: Implementation of the Contacts Service APIs.
+*
+*/
+
+
+//System includes
+
+#include <cvpbkvcardeng.h>//for the vcard engin
+#include <cvpbkcontactmanager.h>// for iContactManager
+#include <mvpbkcontactstore.h>// for iContactStore
+#include <tvpbkcontactstoreuriPtr.h>//used in SetupL
+#include <mvpbkcontactstorelist.h>//used in SetupL to get contact stores
+#include <mvpbkstorecontactfield.h>//used in AddFieldToContactL
+#include <mvpbkstorecontact.h>// used in many function to get the store contact
+#include <mvpbkcontactfieldtextdata.h>//for the field text data
+#include <tvpbkfieldtypemapping.h>//used in CreateFieldTypeL()
+#include <mvpbkfieldtype.h>//return type of CreateFieldTypeL()
+#include <mvpbkcontactoperationbase.h>//for observer
+#include <mvpbkcontactfielddatetimedata.h>//Used in AddDateFieldToContactL
+#include <mvpbkcontactlink.h>//for param in ContactsSaved()
+#include <cvpbkcontactstoreuriarray.h>//used in SetupL
+#include <mvpbkstorecontact.h> // used in many function to get the store contact
+#include <MVPbkContactGroup.h>
+#include <badesca.h>
+#include <mvpbkcontactstoreproperties.h>
+#include <tvpbkcontactstoreuriptr.h>
+#include <MVPbkContactStore.h>
+
+//User includes.
+#include "getliststorelistobserver.h"
+#include "addcontactobserver.h"
+#include "deletecontactobserver.h"
+#include "organisegroupsobserver.h"
+#include "contactretrieveobserver.h"
+#include "contactservice.h"
+
+class CContactIter;
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Static NewL() method to create an instance of the contact service core class.
+// ---------------------------------------------------------------------------
+
+EXPORT_C
+CContactService* CContactService::NewL()
+ {
+ CContactService* self = new( ELeave ) CContactService( );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Destructor for CContactService.
+// ---------------------------------------------------------------------------
+
+CContactService::~CContactService()
+ {
+ iFs.Close();
+ delete iEngine;
+ delete iContactManager;
+ for(TInt i = 0; i < iAsyncObjArray.Count(); i++)
+ {
+ ((iAsyncObjArray[i]).iAsyncObj)->Cancel();
+ }
+ iAsyncObjArray.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+
+CContactService::CContactService()
+ :iErrKey(0)
+ {
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Symbian second-phase constructor
+// ---------------------------------------------------------------------------
+
+void CContactService::ConstructL()
+ {
+ User::LeaveIfError( iFs.Connect() );
+ BaseSetupL(VPbkContactStoreUris::DefaultCntDbUri());
+ }
+
+// METHODS
+// ---------------------------------------------------------------------------
+// Method to setup basic parameters...like creating contact manager instance,
+// and initialising the contact store.
+// ---------------------------------------------------------------------------
+
+TInt CContactService::BaseSetupL(const TDesC& aStoreUri
+ /*MVPbkContactStoreListObserver* aStoreObserver*/)
+ {
+ //Create an instance of uriList and append all the list of URIs to the list.
+
+ CVPbkContactStoreUriArray* uriList =
+ CVPbkContactStoreUriArray::NewLC();
+ uriList->AppendL(TVPbkContactStoreUriPtr(aStoreUri));
+
+ //Instantiate contact manager with the
+ //constucted uri list and file session.
+ iContactManager = CVPbkContactManager::NewL(*uriList,
+ &iFs);
+
+ MVPbkContactStoreList& contactStores = iContactManager->ContactStoresL();
+
+ iContactStore = contactStores.Find(aStoreUri);
+
+ CleanupStack::PopAndDestroy(uriList);
+
+ return KErrNone;
+ }
+
+
+//-----------------------------------------------------------------------------------
+// Open the store specific to Vcard import and export operations.
+//-----------------------------------------------------------------------------------
+
+TInt CContactService::VcardStoreOpenL(const TDesC& aStoreUri,
+ MContactStoreListObserver* aStoreObserver)
+ {
+ iContactManager->LoadContactStoreL(TVPbkContactStoreUriPtr(aStoreUri));
+
+ if( !iEngine )
+ iEngine = CVPbkVCardEng::NewL( *iContactManager );
+
+ aStoreObserver->SetEngine( iEngine );
+
+ // Open the store
+ MVPbkContactStoreList& contactStores = iContactManager->ContactStoresL();
+
+ iContactStore = contactStores.Find(aStoreUri);
+
+ if(!iContactStore)
+ {
+ iContactManager->LoadContactStoreL(TVPbkContactStoreUriPtr(aStoreUri));
+ contactStores = iContactManager->ContactStoresL();
+ iContactStore = contactStores.Find(aStoreUri);
+ }
+ if(iContactStore)
+ {
+ aStoreObserver->SetContactStore( iContactStore );
+ iContactStore->OpenL( *aStoreObserver );
+ return KErrNone;
+ }
+ return KErrGeneral;
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Create data for the operation, prepare the write stream and
+// call the vCardEngine to execute the operation. The results are reported
+// through callback methods.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C
+void CContactService::ExportVCardL(MContactCallback* aCallback,
+ TInt aTransId,
+ const TFileName& aFileName,
+ const TDesC8& aContactId,
+ const TDesC& aStoreUri)
+ {
+ //Check for the validity of the arguments.
+ if( !aContactId.Compare(KNullDesC8) || NULL == aCallback)
+ {
+ User::Leave(KErrArgument);
+ }
+ TInt returncode;
+ CExportStoreListObserver* exportObserver =
+ CExportStoreListObserver::NewL(this,
+ iFs,
+ aFileName,
+ aContactId,
+ aCallback,
+ aTransId);
+
+ CleanupStack::PushL(exportObserver);
+ exportObserver->SetContactService(this);
+ returncode=VcardStoreOpenL(aStoreUri,
+ exportObserver);
+ if(returncode != KErrNone)
+ {
+ User::Leave(returncode);
+ }
+ AddAsyncObjL(aTransId, exportObserver);
+
+ CleanupStack::Pop(exportObserver);
+ }
+
+
+// ---------------------------------------------------------------------------
+// Prepare the read stream and call the vCardEngine to execute the operation.
+// The results are reported through callback methods.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C
+void CContactService::
+ ImportVCardToStoreL(MContactCallback* aCallback,
+ TInt aTransId,
+ const TFileName& aFileName,
+ const TDesC& aStoreUri)
+ {
+ //Check for the validity of the arguments.
+ if(NULL == aCallback)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TInt returncode;
+ CImportStoreListObserver* importObserver =
+ CImportStoreListObserver::NewL(iFs,
+ aFileName,
+ aCallback,
+ aTransId);
+
+ CleanupStack::PushL(importObserver);
+ importObserver->SetContactService(this);
+ returncode=VcardStoreOpenL(aStoreUri,
+ importObserver);
+ if(returncode != KErrNone)
+ {
+ User::Leave(returncode);
+ }
+ AddAsyncObjL(aTransId, importObserver);
+
+ CleanupStack::Pop(importObserver);
+
+ }
+
+// ---------------------------------------------------------------------------
+// This method gets the list of contact stores from the contact manager, finds
+// the specified database from the list and opens the same with the appropriate
+// observer passed to it.
+// If it does not found in the list of stores then loads the same and opens it
+// asynchronously.
+// ---------------------------------------------------------------------------
+
+TInt CContactService::
+GetContactStoreAndOpenL(const TDesC& aStoreUri,
+ MVPbkContactStoreObserver* aStoreObserver)
+ {
+ MVPbkContactStoreList& contactStores = iContactManager->ContactStoresL();
+
+ iContactStore = contactStores.Find(aStoreUri);
+
+ if(!iContactStore)
+ {
+ iContactManager->LoadContactStoreL(TVPbkContactStoreUriPtr(aStoreUri));
+ contactStores = iContactManager->ContactStoresL();
+ iContactStore = contactStores.Find(aStoreUri);
+ }
+ if(iContactStore)
+ {
+ iContactStore->OpenL( *aStoreObserver );
+ return KErrNone;
+ }
+ return KErrGeneral;
+ }
+
+// ---------------------------------------------------------------------------
+// Method which does the following...
+// 1. Adding a new contact to the contact store.
+// 2. Adding a new group to the contact store.
+// 3. Edit an existing contact from the contact store.
+// 4. Edit a group from the contact store.
+// ---------------------------------------------------------------------------
+
+EXPORT_C
+void CContactService::AddL( MContactCallback* aCallback,
+ TInt aTransId,
+ CSingleContact* aStoreContact,
+ const TDesC8& aGroupId,
+ const TDesC& aGroupLabel,
+ const TDesC& aStoreUri )
+ {
+ //Check for the validity of the arguments.
+ //if no new contact, no reference to exiting contact,
+ // no reference to existing grp,
+ //no label to new grp then or no callback fn parameter then,
+ // leave the fn with the error code KErrArgument.
+ if((aStoreContact && aGroupLabel != KNullDesC) || NULL == aCallback )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TInt retVal;
+
+ // Create an instance of addContactObserver
+ CAddContactObserver* addContactObserver =
+ CAddContactObserver::NewL(this,
+ iContactStore,
+ aStoreContact,
+ aGroupId,
+ aGroupLabel,
+ aTransId,
+ aCallback);
+
+ CleanupStack::PushL(addContactObserver);
+
+ retVal = GetContactStoreAndOpenL(aStoreUri,
+ addContactObserver);
+ if(retVal != KErrNone)
+ {
+ User::Leave(retVal);
+ }
+ AddAsyncObjL(aTransId, addContactObserver);
+ CleanupStack::Pop(addContactObserver);
+
+}
+
+
+// ---------------------------------------------------------------------------
+// Method for deleting a contact or list of contacts from the contact store.
+// ---------------------------------------------------------------------------
+
+EXPORT_C
+void CContactService::DeleteL( MContactCallback* aCallback,
+ TInt aTransId,
+ RPointerArray<TDesC8>& aContactIdArray,
+ const TDesC& aStoreUri )
+ {
+ //Check for the validity of the arguments.
+ if( !aCallback || (aContactIdArray.Count()==0))
+ {
+ User::Leave(KErrArgument);
+ }
+ TInt retVal;
+
+ //Intantiate delete contact observer for deleting contacts from the contact store.
+ CDeleteContactObserver* deleteContactsObserver =
+ CDeleteContactObserver::NewL(this,
+ iContactStore,
+ aContactIdArray,
+ aTransId,
+ aCallback );
+
+ CleanupStack::PushL(deleteContactsObserver);
+
+ retVal = GetContactStoreAndOpenL(aStoreUri,
+ deleteContactsObserver);
+ if(retVal != KErrNone)
+ {
+ User::Leave(retVal);
+ }
+ AddAsyncObjL(aTransId, deleteContactsObserver);
+
+ CleanupStack::Pop(deleteContactsObserver);
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Method does the following...
+// 1. Associates one or more contacts to the specified group.
+// 2. Disassociates one or more contacts from specified group.
+// ---------------------------------------------------------------------------
+
+EXPORT_C
+void CContactService::OrganiseGroupsL(MContactCallback* aCallback,
+ TInt aTransId,
+ const TDesC8& aGroupId,
+ RPointerArray<TDesC8>& aContactIdArray,
+ TBool aAssociateFlag,
+ const TDesC& aStoreUri)
+ {
+ //Check for the validity of the arguments.
+ if(!aCallback)
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ TInt retVal;
+ //Create an instance of organise groups observer.
+ COrganiseGroupsObserver* organiseGroupsObserver =
+ COrganiseGroupsObserver::NewL(this,
+ aGroupId,
+ aContactIdArray,
+ aAssociateFlag,
+ aTransId,
+ aCallback,
+ iContactStore);
+
+ CleanupStack::PushL(organiseGroupsObserver);
+
+ retVal = GetContactStoreAndOpenL(aStoreUri,
+ organiseGroupsObserver);
+ if(retVal != KErrNone)
+ {
+ User::Leave(retVal);
+ }
+ AddAsyncObjL(aTransId, organiseGroupsObserver);
+
+ CleanupStack::Pop(organiseGroupsObserver); //organiseGroupsObserver
+ }
+
+//---------------------------------------------------
+//Based on the kind of request for GetListL fetches a list of either contacts, groups or databases.
+//In case of fetching contacts/groups it calls GetContactStoreAndOpenL() for setting up the database before fetching.
+//In case of fetching of list of databases it calls GetContactsDatabases()
+//In both cases the result is to be iterable.
+//It can also be used in retrieving a single contact, in which case iterator is initialized directly.
+//---------------------------------------------------
+EXPORT_C
+void CContactService::GetListL( MContactCallback* aCallback,
+ TInt aTransId,
+ Ttype type,
+ const TDesC8& aContactId,
+ const TDesC& aSearchVal,
+ CSearchFields* aSearchFields,
+ TOrder aSortOrder,
+ const TDesC& aStoreUri)
+ {
+ TInt retVal = KErrGeneral;
+ CContactIter* iter;
+ CGetListStoreListObserver* getListOpenObserver;
+ if(!(aCallback))
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ switch(type)
+ {
+ case EContacts:
+ case EGroups:
+ if(&aContactId && aContactId.Compare(KNullDesC8))
+ {
+ // Create Iterator
+ iter = CContactIter::NewL();
+ CleanupStack::PushL(iter);
+
+ //Extract the contactlink from the contactid
+
+ MVPbkContactLinkArray* linkArray = iContactManager->CreateLinksLC(aContactId);
+ //Open Store using GetContactStoreAndOpenL()
+ //and Create instantiate storelist observer
+ getListOpenObserver =
+ CGetListStoreListObserver::NewL((linkArray->At(0).
+ ContactStore().
+ StoreProperties().
+ Uri().
+ UriDes()),
+ aContactId,
+ aSearchVal,
+ aSearchFields,
+ aSortOrder,
+ aCallback,
+ this,
+ iter,
+ type,
+ aTransId,
+ iContactStore) ;
+
+ CleanupStack::PushL(getListOpenObserver);
+
+ //Opens the database and goes to observer's StoreReady() function.
+ retVal = GetContactStoreAndOpenL( aStoreUri, getListOpenObserver );
+ if(retVal != KErrNone)
+ {
+ User::Leave(retVal);
+ }
+ AddAsyncObjL(aTransId, getListOpenObserver);
+
+
+ CleanupStack::Pop(getListOpenObserver);
+ CleanupStack::PopAndDestroy();//CreateLinksLC()
+ CleanupStack::Pop(iter);
+ break;
+
+ }
+
+ // Create Iterator
+ iter = CContactIter::NewL();
+ CleanupStack::PushL(iter);
+
+
+ //Open Store using GetContactStoreAndOpenL() and Create
+ //instantiate storelist observer
+ getListOpenObserver =
+ CGetListStoreListObserver::NewL(aStoreUri,
+ aContactId,
+ aSearchVal,
+ aSearchFields,
+ aSortOrder,
+ aCallback,
+ this,
+ iter,
+ type,
+ aTransId,
+ iContactStore) ;
+ CleanupStack::PushL(getListOpenObserver);
+
+ //Opens the database and goes to observer's StoreReady() function.
+ retVal = GetContactStoreAndOpenL(aStoreUri,
+ getListOpenObserver);
+ if(retVal != KErrNone)
+ {
+ User::Leave(retVal);
+ }
+ AddAsyncObjL(aTransId, getListOpenObserver);
+
+
+ CleanupStack::Pop(getListOpenObserver);
+ CleanupStack::Pop(iter);
+ break;
+ default:
+ User::Leave(KErrArgument);
+ }
+ }
+
+//---------------------------------------------------
+//Gets the list of databases from the member varible iContactManager
+//and reads the data and sets the iterator with the result.
+//---------------------------------------------------
+EXPORT_C void CContactService::GetListL( CContactIter& aIter )
+ {
+ HBufC* ptr = NULL;
+
+ //Get the list of stores present
+ TInt count=(iContactManager->ContactStoresL()).Count();
+
+ RPointerArray<HBufC> array(count);
+ CleanupClosePushL(array);
+ for(int i=0; i<count; i++)
+ {
+ ptr =
+ iContactManager->ContactStoresL().At(i).StoreProperties().Uri().UriDes().AllocL();
+ CleanupStack::PushL(ptr);
+ array.AppendL(ptr);
+ CleanupStack::Pop(ptr);
+ }
+ //Set the iterator to point to this array
+ aIter.SetDbNamePtr(array, count);
+ CleanupStack::Pop(&array);
+ }
+
+
+const MVPbkFieldTypeList& CContactService::GetFieldTypes()
+ {
+ return iContactManager->FieldTypes();
+ }
+
+
+CVPbkContactManager& CContactService::GetContactManager()
+ {
+ return *iContactManager;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Adds asynchronous request object
+// ---------------------------------------------------------------------------
+//
+void CContactService::AddAsyncObjL(const TInt32 aTransactionId,
+ MCancelAsync* aAsyncObj)
+ {
+ TAsyncRequestInfo asyncRequestInfo;
+ asyncRequestInfo.iTransactionId = aTransactionId;
+ asyncRequestInfo.iAsyncObj = aAsyncObj;
+ iAsyncObjArray.AppendL( asyncRequestInfo );
+ }
+
+// ---------------------------------------------------------------------------
+// Cancels asynchronous request
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CContactService::Cancel( const TInt32 aTransactionId )
+ {
+ TInt pos = iAsyncObjArray.Count() - 1;
+ TAsyncRequestInfo obj;
+ TInt retVal = KErrNotFound;
+
+ for ( ; pos >= 0; pos-- )
+ {
+ obj = iAsyncObjArray[pos];
+ if( obj.iTransactionId == aTransactionId )
+ {
+ obj.iAsyncObj->Cancel();
+ iAsyncObjArray.Remove(pos);
+ iAsyncObjArray.Compress();
+ retVal = KErrNone;
+ }
+ }
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Gets the unsupported field key ID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CContactService :: GetErrKey()
+ {
+ return iErrKey;
+ }
+// ---------------------------------------------------------------------------
+// Notifies Messaging service about the completeion of the request
+// ---------------------------------------------------------------------------
+//
+void CContactService::RequestComplete( const TInt32 aTransactionId )
+ {
+ TInt pos = iAsyncObjArray.Count() - 1;
+ TAsyncRequestInfo obj;
+ for ( ; pos >= 0; pos-- )
+ {
+ obj = iAsyncObjArray[pos];
+ if( obj.iTransactionId == aTransactionId )
+ {
+ iAsyncObjArray.Remove(pos);
+ iAsyncObjArray.Compress();
+ return;
+ }
+ }
+ }
+
+
+//end of file