diff -r 000000000000 -r e686773b3f54 phonebookengines/contactsmodel/tsrc/TestSyncPlugIn/cntsyncphonedata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/contactsmodel/tsrc/TestSyncPlugIn/cntsyncphonedata.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,684 @@ +// Copyright (c) 2007-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 "cntsyncchecker.h" +#include "cntsyncphonedata.h" +#include +#include +#include "cntsyncdata.h" + +#include // CRepository. +#include +#include + +//--------------------------------------------------- +CContactSyncPhonebookData* CContactSyncPhonebookData::NewL(TUint32& aCRKey, CRepository* aRepository) + { + TUid temp; + temp.iUid = 0; + CContactSyncPhonebookData* self = new(ELeave) CContactSyncPhonebookData(temp, aRepository); + self->InternaliseFromCRL(aCRKey); + return self; + } + + +CContactSyncPhonebookData* CContactSyncPhonebookData::NewLC(TUid aPhonebookUid, CRepository* aRepository) + { + CContactSyncPhonebookData* self = new(ELeave) CContactSyncPhonebookData(aPhonebookUid, aRepository); + CleanupStack::PushL(self); + return self; + } + + +CContactSyncPhonebookData::CContactSyncPhonebookData(TUid aPhonebookUid, CRepository* aRepository) + : iPhonebookUid(aPhonebookUid), iPhonebookTemplateId(KNullContactId), iPhonebookGroupId(KNullContactId), iRepository(aRepository) + { + } + +const TDesC& CContactSyncPhonebookData::TemplateLabel() + { + _LIT(KPhbkTemplateADN,"SIM Card Contacts ADN"); // should be in a resource file for localisation really ;) + _LIT(KPhbkTemplateSDN,"SIM Card Contacts SDN"); + _LIT(KPhbkTemplateLND,"SIM Card Contacts LND"); + _LIT(KPhbkTemplateUSimApp,"SIM Card Contacts USIMAPP"); + _LIT(KPhbkTemplateFDN,"SIM Card Contacts FDN"); + _LIT(KPhbkTemplateNotSpecified,"SIM Card Contacts Name Not Specified"); + + + /* Some Contacts test code used to set group names + _LIT(KGlobalAdnGroupName,"Global Adn Group"); + _LIT(KGlobalSdnGroupName,"Global Sdn Group"); + _LIT(KGlobalLdnGroupName,"Global Lnd Group"); + _LIT(KUsimAppAdnGroupName,"Usim App Adn Group"); + */ + + switch (iPhonebookUid.iUid) + { + case KUidIccGlobalAdnPhonebookValue: + return KPhbkTemplateADN; + + case KUidIccGlobalSdnPhonebookValue: + return KPhbkTemplateSDN; + + case KUidIccGlobalLndPhonebookValue: + return KPhbkTemplateLND; + + case KUidUsimAppAdnPhonebookValue: + return KPhbkTemplateUSimApp; + + case KUidIccGlobalFdnPhonebookValue: + return KPhbkTemplateFDN; + + default: + break; + } + + return KPhbkTemplateNotSpecified; + } + + +CContactSyncPhonebookData::~CContactSyncPhonebookData() + { + delete iIccTemplate; + iStatusArray.Close(); + iPhonebookContacts.ResetAndDestroy(); + } + + +void CContactSyncPhonebookData::AddPhonebookContactL(const TDesC& aName, const TDesC& aNumber) + { + iPhonebookContacts.AppendL(CPhonebookContact::NewLC(aName, aNumber, iRepository)); + CleanupStack::Pop(); // CPhonebookContact + } + + +TInt CContactSyncPhonebookData::SynchronisePhonebook(CContactDatabase& aDb, TInt aCompletionError, TInt aLeaveError) + { + TInt error(KErrNone); + + __ASSERT_DEBUG(iIsSynchronised == EFalse, User::Invariant()); + + + if ((aCompletionError == KErrNone) && (aLeaveError == KErrNone)) + { + // Validate any template ID remembered from previous test + if ((iPhonebookTemplateId != KNullContactId) && // if value has not been set + (iPhonebookTemplateId != KGoldenTemplateId) ) // internally initialised value by cntmodel + { + TRAP(error, ValidateTemplateIdAndLabelL(aDb)); + + if (error) + { + if (error != KErrNotFound) + { + return error; + } + iPhonebookTemplateId = KNullContactId; + } + } + + // Need to create a new template? + if ((iPhonebookTemplateId == KNullContactId) || // if value has not been set + (iPhonebookTemplateId == KGoldenTemplateId)) // internally initialised value by cntmodel + { + if (iIccTemplate) + { + delete iIccTemplate; + iIccTemplate = NULL; + } + + TRAP(error, CreateTemplateIdL(aDb)); // First create Template ID + + if (error == KErrNone) + { + // cache template + TRAP(error, iIccTemplate = aDb.ReadContactL(iPhonebookTemplateId)); + } + + if (error) + { + return error; + } + } + + + + // Validate any group ID remembered from previouzs test + if ((iPhonebookGroupId != KNullContactId) && // if value has not been set + (iPhonebookGroupId != KGoldenTemplateId) ) // internally initialised value by cntmodel + { + TRAP(error, ValidateGroupIdAndTemplateL(aDb)); + + if (error) + { + if (error != KErrNotFound) + { + return error; + } + iPhonebookGroupId = KNullContactId; + } + } + + if ((iPhonebookGroupId == KNullContactId) || // if value has not been set + (iPhonebookGroupId == KGoldenTemplateId) ) // internally initialised value by cntmodel + { + // Now create group ID for this phonebook + TRAP(error, CreateGroupIdL(aDb)); + } + + if (error == KErrNone && iPhonebookContacts.Count() > 0) + { + TRAP(error, SynchroniseContactsL(aDb)); + } + + if (error) + { + return error; + } + + // successfully synchronised + iIsSynchronised = ETrue; + } + + + CompleteNotificationRequest(aCompletionError); + iSynchronisedLeaveCode = aLeaveError; + + // simulated synchronisation completed + return KErrNone; + } + + +void CContactSyncPhonebookData::ValidateTemplateIdAndLabelL(CContactDatabase& aDb) + { + CContactItem* item = aDb.ReadContactLC(iPhonebookTemplateId); + + // The following test confirms if a template ID relates to this phonebook's + // template by checking the label employed. + if ((item->Type() != KUidContactCardTemplate) || + (static_cast(item)->GetTemplateLabelL() != TemplateLabel())) + { + iPhonebookTemplateId = KNullContactId; + } + + CleanupStack::PopAndDestroy(item); + } + + +void CContactSyncPhonebookData::ValidateGroupIdAndTemplateL(CContactDatabase& aDb) + { + CContactGroup* group = static_cast (aDb.ReadContactL(iPhonebookGroupId)); + + CleanupStack::PushL(group); + + // check that contact id refers to a group + if (group->Type() == KUidContactGroup) + { + // Retrieve the first entry in the group, and check that entry's template ID + CContactIdArray* itemList = group->ItemsContainedLC(); + if (itemList->Count() > 0) + { + CContactItem* groupItem = aDb.ReadContactLC((*itemList)[0]); + if (groupItem) + { + if (groupItem->TemplateRefId() != iPhonebookTemplateId) + { + // wrong group + iPhonebookGroupId = KNullContactId; + } + CleanupStack::PopAndDestroy(groupItem); + } + } + CleanupStack::PopAndDestroy(itemList); + } + else + { + // id is not really a group + iPhonebookGroupId = KNullContactId; + } + + CleanupStack::PopAndDestroy(group); + } + + +/** + Create Template UID for the phonebook. + + (Beware - can leave partially created Template) + + @param aDb Handle to the contacts database. + */ +void CContactSyncPhonebookData::CreateTemplateIdL(CContactDatabase &aDb) + { + __ASSERT_DEBUG((iPhonebookTemplateId == KNullContactId || iPhonebookTemplateId == KGoldenTemplateId), User::Invariant()); + + // First check if there is an existing template in the contact database for this phonebook + CContactIdArray* idList = aDb.GetCardTemplateIdListL(); + if (idList) + { + CleanupStack::PushL(idList); + const TInt idListCount = idList->Count(); + if (idListCount > 0) + { + TInt i; + for (i = 0; i < idListCount; i++) + { + CContactCardTemplate* item = static_cast (aDb.ReadContactLC((*idList)[i])); + if (item->GetTemplateLabelL() == TemplateLabel()) + { + iPhonebookTemplateId = (*idList)[i]; + i = idListCount; // force loop to exit + } + CleanupStack::PopAndDestroy(item); + } + } + CleanupStack::PopAndDestroy(idList); + } + + // If no suitable template been found create a new one + if (iPhonebookTemplateId == KNullContactId || + iPhonebookTemplateId == KGoldenTemplateId) + { + // "Creating template for this phonebook" + + CContactItem* newTemplate = aDb.CreateContactCardTemplateLC(TemplateLabel()); + + TContactItemId templateId = newTemplate->Id(); + CleanupStack::PopAndDestroy(newTemplate); + + // Remove all the unnecessary fields + newTemplate = aDb.OpenContactLX(templateId); + CleanupStack::PushL(newTemplate); + const TInt fieldCount = newTemplate->CardFields().Count(); + for(TInt i=fieldCount-1;i>=0;i--) + newTemplate->RemoveField(i); + + // Add default name field + CContactItemField* name = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName); + + name->SetLabelL(_L("Name")); + name->SetMapping(KUidContactFieldVCardMapUnusedN); + newTemplate->AddFieldL(*name); + CleanupStack::Pop(name); + + // Add second name field + CContactItemField* secondName = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldSecondName); + secondName->SetLabelL(_L("Additional Name")); + secondName->SetMapping(KUidContactFieldVCardMapSECONDNAME); + secondName->SetUserFlags(EContactCategoryHome); + newTemplate->AddFieldL(*secondName); + CleanupStack::Pop(secondName); + + // Add default number field + CContactItemField* number = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldPhoneNumber); + number->SetLabelL(_L("Phone Number")); + number->SetMapping(KUidContactFieldVCardMapTEL); + number->AddFieldTypeL(KUidContactFieldVCardMapWORK); + number->AddFieldTypeL(KUidContactFieldVCardMapVOICE); + number->AddFieldTypeL(KUidContactFieldVCardMapCELL); + newTemplate->AddFieldL(*number); + CleanupStack::Pop(number); + + // Add Slot Number field + CContactItemField* slotnum = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldICCSlot); + slotnum->SetLabelL(_L("Slot")); + slotnum->SetMapping(KUidContactFieldVCardMapNotRequired); + newTemplate->AddFieldL(*slotnum); + CleanupStack::Pop(slotnum); + + // Add Phonebook type field + CContactItemField* phonebook = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldICCPhonebook); + phonebook->SetLabelL(_L("Phonebook UID")); + phonebook->SetMapping(KUidContactFieldVCardMapNotRequired); + newTemplate->AddFieldL(*phonebook); + CleanupStack::Pop(phonebook); + + // presume this is a 3G ICC so there are additional fields for ADN and USIM App phonebooks + if((iPhonebookUid.iUid == KUidIccGlobalAdnPhonebookValue) || + (iPhonebookUid.iUid == KUidUsimAppAdnPhonebookValue)) + { + // Add e-mail field + CContactItemField* emailField = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldEMail); + emailField->SetLabelL(_L("Email")); + emailField->SetMapping(KUidContactFieldVCardMapEMAILINTERNET); + emailField->AddFieldTypeL(KUidContactFieldVCardMapWORK); + emailField->SetUserFlags(EContactCategoryOther); + newTemplate->AddFieldL(*emailField); + CleanupStack::Pop(emailField); + + // Add group field - this is different from contacts group. This field indicates + // group that this ICC entry belongs to. User can add this entry to a number of + // groups on ICC i.e. business, private, etc. + CContactItemField* group = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldICCGroup); + group->SetLabelL(_L("Group")); + group->SetMapping(KUidContactFieldVCardMapUnusedN); + newTemplate->AddFieldL(*group); + CleanupStack::Pop(group); + } + + // Now that we know nothing as left, assign member variables (this avoids member variables being left in a bad state in the event of a leave). + iPhonebookTemplateId = templateId; + + aDb.CommitContactL(*newTemplate); + CleanupStack::PopAndDestroy(2); // newTemplate plus locked record + } + } + + +/** + Create Group UID for the phonebook. + @param aDb Handle to the contacts database. + */ +void CContactSyncPhonebookData::CreateGroupIdL(CContactDatabase &aDb) + { + __ASSERT_DEBUG((iPhonebookGroupId == KNullContactId || + iPhonebookGroupId == KGoldenTemplateId), User::Invariant()); + + // First check if there is an existing group in the contact database for this phonebook + CContactIdArray* idList = aDb.GetGroupIdListL(); + if (idList) + { + CleanupStack::PushL(idList); + + const TInt idListCount = idList->Count(); + if (idListCount > 0) + { + TInt i; + for (i = 0; i < idListCount; i++) + { + // Retrieve the first entry in each group, and check that entry's template ID + CContactGroup* group = static_cast (aDb.ReadContactLC((*idList)[i])); + CContactIdArray* itemList = group->ItemsContainedLC(); + if (itemList->Count() > 0) + { + CContactItem* groupItem = aDb.ReadContactLC((*itemList)[0]); + if (groupItem->TemplateRefId() == iPhonebookTemplateId) + { + iPhonebookGroupId = (*idList)[i]; + i = idListCount; // force exit from loop + } + CleanupStack::PopAndDestroy(groupItem); + } + CleanupStack::PopAndDestroy(2, group); // itemList, group + } + } + + CleanupStack::PopAndDestroy(idList); + } + + // If no suitable group has been found create a new one + if (iPhonebookGroupId==KNullContactId || + iPhonebookGroupId==KGoldenTemplateId) + { + CContactItem* group = aDb.CreateContactGroupLC(KNullDesC); + iPhonebookGroupId = group->Id(); + CleanupStack::PopAndDestroy(group); + } + } + + +void CContactSyncPhonebookData::SynchroniseContactsL(CContactDatabase &aDb) + { + const TInt nContacts = iPhonebookContacts.Count(); + + // simple version of phonebook sync + for (TInt idx = 0; idx < nContacts; ++idx) + { + CContactICCEntry* item = CContactICCEntry::NewL(*iIccTemplate); + CleanupStack::PushL(item); + + CContactItemFieldSet& fieldSet = item->CardFields(); + + // add name text + TInt pos = fieldSet.Find(KUidContactFieldFamilyName); + if (pos != KErrNotFound) + { + fieldSet[pos].TextStorage()->SetTextL(*iPhonebookContacts[idx]->Name()); + } + + // add phone number + pos = fieldSet.Find(KUidContactFieldPhoneNumber); + if (pos != KErrNotFound) + { + fieldSet[pos].TextStorage()->SetTextL(*iPhonebookContacts[idx]->Number()); + } + + // ICC Phonebook slot + pos = fieldSet.Find(KUidContactFieldICCSlot); + if (pos != KErrNotFound) + { + TBuf16<20> numberBuffer; + numberBuffer.Format(_L("%d"), idx + 1); + fieldSet[pos].TextStorage()->SetTextL(numberBuffer); + } + + TContactItemId id = aDb.AddNewContactL(*item); + + + + CleanupStack::PopAndDestroy(item); + + // debug print fields + CContactItem* contact = aDb.ReadContactLC(id); + + CContactItemFieldSet& contactFields = contact->CardFields(); + const TInt fieldCount = contactFields.Count(); + + for (TInt i=0; i < fieldCount; i++) + { + CContactItemField &field = contactFields[i]; + if (field.StorageType() == KStorageTypeText) + { + TPtrC fieldText = field.TextStorage()->Text(); + TPtrC labelText = field.Label(); + RDebug::Print(_L("--Field(%d) %S: %S \n\r"), i, &labelText, &fieldText); + } + } + CleanupStack::PopAndDestroy(contact); + + } + + if (nContacts) + { + aDb.CompactL(); + } + } + + +void CContactSyncPhonebookData::ResetSynchronised(TBool aResetTemplateAndGroupIds) + { + if (aResetTemplateAndGroupIds) + { + iPhonebookTemplateId = KNullContactId; + iPhonebookGroupId = KNullContactId; + } + + // tell observers that synchronisation state has changed + CompleteNotificationRequest(KErrNone); + + // not synchronised + iIsSynchronised = EFalse; + iSynchronisedLeaveCode = KErrNone; + } + + +TInt CContactSyncPhonebookData::StoreNotificationRequest(TInt aStatus) + { +// aStatus = KRequestPending; + iNotificationPending++; + return iStatusArray.Append(aStatus); + } + + +void CContactSyncPhonebookData::CompleteNotificationRequest(TInt aError) + { + const TInt count = iStatusArray.Count(); + + for (TInt k = count; k > 0; --k) + { + iNotificationPending--; + RProperty::Set( + SyncNotification::KPropertyCategory, + iPhonebookUid.iUid, + aError); + } + iErrorCode = aError; + iStatusArray.Reset(); + } + +void CContactSyncPhonebookData::CancelNotificationRequestL() + { + const TInt count = iStatusArray.Count(); + RProperty property; + + for (TInt k = count; k > 0; --k) + { + iNotificationPending--; + User::LeaveIfError(property.Attach(SyncNotification::KPropertyCategory,iPhonebookUid.iUid)); + property.Cancel(); + } + iStatusArray.Reset(); + } + + +TInt CContactSyncPhonebookData::NotificationPendingCount() + { + return iStatusArray.Count(); + } + + +void CContactSyncPhonebookData::SetTemplateId(TInt aPhonebookTemplateId) + { + iPhonebookTemplateId = aPhonebookTemplateId; + } + + +void CContactSyncPhonebookData::SetGroupId(TInt aPhonebookGroupId) + { + iPhonebookGroupId = aPhonebookGroupId; + } + + +const TUid& CContactSyncPhonebookData::PhonebookUid() + { + return iPhonebookUid; + } + + +TInt CContactSyncPhonebookData::TemplateId() + { + return iPhonebookTemplateId; + } + + +TInt CContactSyncPhonebookData::GroupId() + { + return iPhonebookGroupId; + } + + +void CContactSyncPhonebookData::SetSynchronisedLeaveCode(TInt aLeaveError) + { + iSynchronisedLeaveCode = aLeaveError; + } + + +void CContactSyncPhonebookData::SetSynchronised(TInt aSynchronised) + { + iIsSynchronised = aSynchronised; + } + + +TBool CContactSyncPhonebookData::IsSynchronisedL() + { + User::LeaveIfError(iSynchronisedLeaveCode); + return iIsSynchronised; + } + + +TBool CContactSyncPhonebookData::SynchroniseRequired() + { + return !iIsSynchronised; + } + +void CContactSyncPhonebookData::InternaliseFromCRL(TUint32& aCRKey) + { + TInt temp; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, temp, *iRepository); + iPhonebookUid.iUid = temp; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, temp, *iRepository); + iPhonebookTemplateId = temp; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, temp, *iRepository); + iPhonebookGroupId = temp; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, iIsSynchronised, *iRepository); + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, iNotificationPending, *iRepository); + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, iErrorCode, *iRepository); + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, iSynchronisedLeaveCode, *iRepository); + TInt notificationVectorSize = 0; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, notificationVectorSize, *iRepository); + for (TInt i = 0 ; i < notificationVectorSize ; i++) + { + TInt notification; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, notification, *iRepository); + iStatusArray.Append(notification); + } + TInt numberOfPhonebookContacts = 0; + CContactSyncStaticRepository::ReadIntFromCentralRepositoryL(aCRKey, numberOfPhonebookContacts, *iRepository); + aCRKey+=10 - iStatusArray.Count(); + for (TInt i2 = 0 ; i2 < numberOfPhonebookContacts ; i2++) + { + CPhonebookContact* temp; + temp = CPhonebookContact::NewL(aCRKey, iRepository); + iPhonebookContacts.Append(temp); + } + aCRKey+=10; + } + +void CContactSyncPhonebookData::ExternaliseToCRL(TUint32& aCRKey) + { + TInt temp = iPhonebookUid.iUid; + //TRAP(Err, iRepository->Set(aCRKey++, temp)); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, temp, *iRepository); + + temp = iPhonebookTemplateId; + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, temp, *iRepository); + temp = iPhonebookGroupId; + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, temp, *iRepository); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, iIsSynchronised, *iRepository); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, iNotificationPending, *iRepository); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, iErrorCode, *iRepository); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, iSynchronisedLeaveCode, *iRepository); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, iStatusArray.Count(), *iRepository); + for (TInt i = 0 ; i < iStatusArray.Count() ; i++) + { + TInt notification(iStatusArray[i]); + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, notification, *iRepository); + } + CContactSyncStaticRepository::WriteIntToCentralRepositoryL(aCRKey, iPhonebookContacts.Count(), *iRepository); + aCRKey+=10 - iStatusArray.Count(); + for (TInt i2 = 0 ; i2 < iPhonebookContacts.Count() ; i2++) + { + CPhonebookContact* temp = iPhonebookContacts[i2]; + temp->WriteToCRL(aCRKey); + } + aCRKey+=10; + } + +TInt CContactSyncPhonebookData::ErrorCode() + { + return iErrorCode; + } + +