diff -r 8173571d354e -r 1fc85118c3ae locationdataharvester/mylocationsengine/src/mylocationsengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locationdataharvester/mylocationsengine/src/mylocationsengine.cpp Tue Aug 31 15:09:25 2010 +0300 @@ -0,0 +1,1829 @@ +/* +* Copyright (c) 2010 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: Mylocation engine source implementation for location picker +* and maptile service. +* +*/ + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "contactsubscriber.h" +#include "calendarsubscriber.h" +#include "mylocationsengine.h" +#include "geocodeupdate.h" //header for GeocodeUpdate class +//handle for CMyLocationsHistoryDbObserver class +#include "mylocationlogger.h" +#if ( defined __WINSCW__ ) || ( defined __WINS__ ) +_LIT ( KImageStorageDrive, "C:\\MapTile\\"); +#endif +_LIT(KFolderName,":\\MapTile\\"); +const TInt KImagePathSize=36; +const TInt KDefaultFilePathSize = 20; +const TUid KMaptileStatusPublish={0x2002680A}; +enum TMaptileStatusKeys {EMaptileStatusInteger=0x1}; + +//Protocol : [appid-addresstype-maptilestatus] +_LIT8( KMaptileStatusFormat, "%d-%d-%d" ); +const TInt KProtocolBufferSize = 16; + +const QString KSpace(" "); + +// ============================ MEMBER FUNCTIONS =============================== + +CMyLocationsEngine* CMyLocationsEngine::NewL() +{ + CMyLocationsEngine* self = new (ELeave) CMyLocationsEngine(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::ConstructL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::ConstructL() +{ + __TRACE_CALLSTACK; + CActiveScheduler::Add(this); + + //Connection to Landmark DB + iLandmarkDb = CPosLandmarkDatabase::OpenL(); + ExecuteAndDeleteLD(iLandmarkDb->InitializeL()); + + MYLOCLOGSTRING("Connection to Landmark DB."); + // create CMyLocationsDatabaseManager instance + iMyLocationsDatabaseManager = new (ELeave) CMyLocationsDatabaseManager; + iMyLocationsDatabaseManager->ConstructL(); + + MYLOCLOGSTRING("create CMyLocationsDatabaseManager instance"); + + TRAPD( error , iMapTileInterface = CMapTileInterface::NewL()); + if( error == KErrNone ) + { + iMaptileGeocoderPluginAvailable = ETrue; + } + + MYLOCLOGSTRING("iMapTileInterface = CMapTileInterface::NewL()"); + //Maptile Db instance + iMaptileDatabase = CLookupMapTileDatabase::NewL(KMapTileLookupDatabaseName); + + MYLOCLOGSTRING("Maptile Db instance created "); + + iGeocodeUpdate = new GeocodeUpdate(); + iMyLocationThreeAMTimer = CLocationGeoTagTimerAO::NewL(*this); + + iMyLocationThreeAMTimer->StartTimer(); + + MYLOCLOGSTRING(" iMyLocationThreeAMTimer = CLocationGeoTagTimerAO::NewL(this)"); + + //Create instance of contact manager + iContactManager = new QContactManager(); + + MYLOCLOGSTRING(" start contact db observation "); + StartContactsChangeNotifierL(); + + //set the folder path to store maptile + imageFilePath.Zero(); + SetFolderPathL(); + + TInt status = KErrNone; + iCalSession = CCalSession::NewL(); + NotifyChangeL(status); + + // Start listening to landmarks db changes + StartLandmarksChangeNotifier(); + iContactSubscriber = CContactSubscriber::NewL(this); + iCalendarSubscriber = CCalendarSubscriber::NewL(this); + TInt ret = RProperty::Define( KMaptileStatusPublish, EMaptileStatusInteger, RProperty::EByteArray ); + +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::SetFolderPath() +// set folder path structure +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::SetFolderPathL() +{ + __TRACE_CALLSTACK; + RFs session; + User::LeaveIfError(session.Connect()); + + if ( imageFilePath.Length() > 0 && BaflUtils::FolderExists(session, imageFilePath)) + { + session.Close(); + MYLOCLOGSTRING("Image folder path exists"); + return; + } + const TUint EMediaMemoryCard = 0x000014; + imageFilePath.Zero(); +#if ( defined __WINSCW__ ) || ( defined __WINS__ ) + imageFilePath.Copy(KImageStorageDrive); + MYLOCLOGSTRING("using in debug mode"); +#else + TVolumeInfo vol; + TInt driveNumber = EDriveE; + TChar driveLetter; + TDriveInfo driveInfo; + TInt error( KErrNone ); + error=session.Volume(vol, driveNumber); + MYLOCLOGSTRING1("E drive volume info status -%d",error); + if (error == KErrNone) + { + error = session.Drive(driveInfo, driveNumber); + MYLOCLOGSTRING1("E driveinfo status -%d",error); + switch(driveInfo.iType) + { + case EMediaFlash: + case EMediaHardDisk: + case EMediaNANDFlash: + case EMediaMemoryCard: + case EMediaCdRom: + { + MYLOCLOGSTRING(" E drive match case"); + session.DriveToChar( driveNumber , driveLetter ); + imageFilePath.Append(driveLetter); + imageFilePath.Append(KFolderName); + break; + } + default: + break; + + }; + } + + if (!imageFilePath.Length() > 0) + { + driveNumber = EDriveF; + error = session.Volume(vol, driveNumber); + MYLOCLOGSTRING1("F drive volume info status -%d",error); + + if (error == KErrNone) + { + error = session.Drive(driveInfo, driveNumber); + MYLOCLOGSTRING1("F drive info status-%d", error); + + switch (driveInfo.iMediaAtt) + { + /** Solid-state media. */ + case EMediaFlash: + case EMediaHardDisk: + case EMediaNANDFlash: + case EMediaMemoryCard: + { + MYLOCLOGSTRING("F drive exist as this type"); + session.DriveToChar(driveNumber, driveLetter); + imageFilePath.Append(driveLetter); + imageFilePath.Append(KFolderName); + break; + } + + default: + break; + + }; + } + } +#endif + if (imageFilePath.Length()>0 && !BaflUtils::FolderExists(session, imageFilePath)) + { + session.MkDirAll(imageFilePath); + MYLOCLOGSTRING("folder path does not exist , created "); + } + session.Close(); +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::CMyLocationsEngine() +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CMyLocationsEngine::CMyLocationsEngine() : + CActive(EPriorityStandard), + iCalSession(NULL), + iCalView(NULL), + iContactsDb(NULL), + iContactChangeNotifier(NULL), + iLandmarkDb(NULL), + iMapTileInterface(NULL), + iMyLocationsDatabaseManager(NULL), + iMaptileDatabase(NULL), + iMyLocationThreeAMTimer(NULL), + iMaptileGeocoderPluginAvailable(EFalse), + iCalenderNotification(NULL), + iContactManager(NULL), + iContactSubscriber(NULL), + iCalendarSubscriber(NULL), + iGeocodeUpdate(NULL), + iLastContactId( -1 ) , + iLastCalendarId( 0 ) +{ + +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::~CMyLocationsEngine() +// Destructor. +// ----------------------------------------------------------------------------- +// +CMyLocationsEngine::~CMyLocationsEngine() +{ + __TRACE_CALLSTACK;// delete the member variables. + + Cancel(); + + delete iContactChangeNotifier; + + delete iMyLocationsDatabaseManager; + + delete iLandmarkDb; + + delete iContactsDb; + + delete iCalView; + + delete iCalSession; + + delete iMapTileInterface; + + delete iMaptileDatabase; + + delete iCalenderNotification; + + delete iMyLocationThreeAMTimer; + + delete iContactManager; + + delete iContactSubscriber; + + delete iCalendarSubscriber; + + delete iGeocodeUpdate; + + for( TInt index = 0; index < iAddressInfo.Count(); index++ ) + { + delete iAddressInfo[index]; + iAddressInfo.Remove(index); + iAddressInfo.Compress(); + } + + iAddressInfo.Reset(); + +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::NotifyChangeL() +// Starts calender db create notification to get callbacks. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::NotifyChangeL(TInt &aStatus) +{ + __TRACE_CALLSTACK; + + TBufC defaultFile = iCalSession->DefaultFileNameL(); + TChar drive = defaultFile[0]; + TRAP(aStatus, iCalSession->OpenL( defaultFile )); + MYLOCLOGSTRING1("iCalSession->OpenL() status-%d",aStatus); + if ( KErrNone == aStatus ) + { + // create a calendar entry view with the opened session + iCalView = CCalEntryView::NewL(*iCalSession); + StartCalenderChangeNotifierL(); + } + else + { + if( !iCalenderNotification ) + { + iCalenderNotification = CCalenderNotification::NewL( this ); + } + + + iCalenderNotification->CheckCalenderDbFileStructure( drive ); + } +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::GetChangeNoficationL() +// To get callbacks through publisher from contact context +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::GetChangeNotificationL( TInt &aId, TInt& addressType, TInt& addressCount ) +{ + __TRACE_CALLSTACK; + + iLastContactId = aId; + + //If the requested id is already in queue, just return + for( TInt index = 0 ; index < iMapTileRequestQueue.Count(); index++ ) + { + if( iLastContactId == iMapTileRequestQueue[index]->iUId ) + { + MYLOCLOGSTRING("contact id is in queue"); + return; + } + } + + TAppAddressInfo* addressInfo = new (ELeave) TAppAddressInfo; + addressInfo->iUid = aId; + addressInfo->iAddressType = addressType; + //Memory will be freed when the queue is deleted + if( iAddressInfo.Append(addressInfo) != KErrNone ) + { + delete addressInfo; + } + + //Get all 3 adress + if( addressCount > 1 && iAddressInfo.Count() < addressCount ) + return; + + + for( TInt index = 0; index < iAddressInfo.Count(); index++ ) + { + TUidSourceType type = static_cast(iAddressInfo[index]->iAddressType ); + + //if type is contact + if( type == ESourceContactsPref || type == ESourceContactsWork || + type == ESourceContactsHome ) + { + QContact contactInfo = iContactManager->contact( iAddressInfo[index]->iUid ); + + CPosLandmark *contactAddressLm = NULL; + + TInt itemCount = 0; + + foreach ( QContactAddress address, contactInfo.details() ) + { + QStringList context = address.contexts(); + if ( context.isEmpty() && type == ESourceContactsPref ) // no context + { + contactAddressLm = GetContactAddressDetailsLC( address ); + itemCount++; + break; + } + else if ( !context.isEmpty() && context.first() == QContactAddress::ContextHome && + type == ESourceContactsHome ) + { + contactAddressLm = GetContactAddressDetailsLC( address ); + itemCount++; + break; + } + else if ( !context.isEmpty() && context.first() == QContactAddress::ContextWork && + type == ESourceContactsWork ) + { + contactAddressLm = GetContactAddressDetailsLC( address ); + itemCount++; + break; + } + } + + //Update the entry with inprogress status + TLookupItem lookupItem; + lookupItem.iUid = iAddressInfo[index]->iUid; + lookupItem.iSource = type; + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + iMaptileDatabase->UpdateEntryL( lookupItem ); + + //Request for maptile fetching + if( contactAddressLm ) + { + RequestMapTileImageL( *contactAddressLm, type, + iAddressInfo[index]->iUid, EContactDbObserverEventContactChanged ); + } + + CleanupStack::PopAndDestroy( itemCount ); + } + } + for( TInt index = 0; index < iAddressInfo.Count(); index++ ) + { + //free the allocated memory + delete iAddressInfo[index]; + iAddressInfo.Remove(index); + iAddressInfo.Compress(); + } + + iAddressInfo.Reset(); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::SubscribeFromCalendarL() +// To get callbacks through publisher from calendar context +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::SubscribeFromCalendarL(TInt aId) +{ + __TRACE_CALLSTACK; + iLastCalendarId = aId; + for ( int index =0;iMapTileRequestQueue.Count()>index ;index++) + { + if( iLastCalendarId == iMapTileRequestQueue[index]->iUId ) + { + return; + } + } + + CCalEntry* calEntry = NULL; + calEntry = iCalView->FetchL(aId); + CleanupStack::PushL(calEntry); + TPtrC address(calEntry->LocationL()); + if( address.Length()>0 ) + { + TLookupItem lookupItem; + lookupItem.iUid = aId; + lookupItem.iSource = ESourceCalendar; + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + iMaptileDatabase->UpdateEntryL( lookupItem ); + RequestMapTileImageL( address, ESourceCalendar, aId , EChangeModify ); + } + CleanupStack::PopAndDestroy(calEntry); +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::StartCalenderChangeNotifierL() +// Starts calender change notification method to get callbacks when entries are +// added/modified/deleted in contacts +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::StartCalenderChangeNotifierL() +{ + __TRACE_CALLSTACK;// Get the current time and set Calendar filter to consider entries whose start time + // fall under the timeframe one year past and one year ahead of the current time. + if (iCalSession) + { + MYLOCLOGSTRING("iCalSession is not null"); + TTime currentTime; + currentTime.HomeTime(); + + TTime startTime = currentTime - TTimeIntervalYears(1); + TTime endTime = currentTime + TTimeIntervalYears(1); + + TCalTime calStartTime; + calStartTime.SetTimeLocalL(startTime); + + MYLOCLOGSTRING("SetTimeLocalL(startTime)"); + + TCalTime calEndTime; + calEndTime.SetTimeLocalL(endTime); + + MYLOCLOGSTRING("SetTimeLocalL(endTime)"); + + // set the filter for modification tracking + CCalChangeNotificationFilter *filter = + CCalChangeNotificationFilter::NewL( + MCalChangeCallBack2::EChangeEntryAll, ETrue, + CalCommon::TCalTimeRange(calStartTime, calEndTime)); + MYLOCLOGSTRING(" CCalChangeNotificationFilter::NewL()"); + // 'this' object implements MCalChangeCallBack + iCalSession->StartChangeNotification(*this, *filter); + } +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::StartContactsChangeNotifierL() +// Starts contacts change notification method to get callbacks when entries are +// added/modified/deleted in contacts +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::StartContactsChangeNotifierL() +{ + __TRACE_CALLSTACK; + + iGeocodeUpdate->createContactdb(); + iContactsDb = CContactDatabase::OpenL(); + // Create CContactChangeNotifier object with 'this' object. + iContactChangeNotifier = CContactChangeNotifier::NewL(*iContactsDb,this); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::StartLandmarksChangeNotifier() +// Starts landmarks change notification method to get callbacks when entries are added/modified/deleted in landmarks +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::StartLandmarksChangeNotifier() +{ + __TRACE_CALLSTACK;// Resume event listening + iLandmarkDb->NotifyDatabaseEvent(iLmEvent, iStatus); + SetActive(); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::CalChangeNotification() +// Callback when there is a change in the calendar database. +// ----------------------------------------------------------------------------- +// + +void CMyLocationsEngine::CalChangeNotification( + RArray& aChangeItems) +{ + __TRACE_CALLSTACK; + + if(iCalenderNotification) + { + delete iCalenderNotification; + iCalenderNotification = NULL; + } + + // get entries associated with this UID + for (int i = 0; i < aChangeItems.Count(); i++) + { + + // Check if this is some undefined change in calendar db. + if( aChangeItems[0].iChangeType == EChangeUndefined && aChangeItems[0].iEntryType == EChangeEntryAll ) + { + // Refresh the calendar related entries in the location and maptiledb. + RefreshCalendarEntryListL(); + break; + } + TCalChangeEntry calChangeEntry = aChangeItems[i]; + iEventType = calChangeEntry.iChangeType; + switch (calChangeEntry.iChangeType) + { + case EChangeAdd: + { + + TRAP_IGNORE(CalenderEntryAddedL(calChangeEntry)); + break; + } + + case EChangeModify: + { + if (iMapTileRequestQueue.Count() > 0) + { + if (calChangeEntry.iEntryId == iMapTileRequestQueue[0]->iUId) + { + return; + } + } + TRAP_IGNORE( CalenderEntryModifyL(calChangeEntry) ) ; + break; + } + case EChangeDelete: + { + TLookupItem lookupItem; + lookupItem.iSource = ESourceCalendar; + lookupItem.iUid = calChangeEntry.iEntryId; + TRAP_IGNORE(ManipulateMapTileDataBaseL(lookupItem)); + TRAP_IGNORE( UpdateDatabaseL( NULL, + calChangeEntry.iEntryId, ESourceCalendar, EEntryDeleted ) ); + break; + } + }; + + } +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::RefreshCalendarEntryListL() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::RefreshCalendarEntryListL() +{ + //Get all the calendar ids and check its validity. + //Delete if they are no more valid. + RArray ids; + iMaptileDatabase->GetAllCalendarIdsL( ids ); + for( TInt i = 0; i < ids.Count(); i++ ) + { + if( !IsCalendarEntryValidL( ids[i] ) ) + { + TLookupItem lookupItem; + lookupItem.iSource = ESourceCalendar; + lookupItem.iUid = ids[i]; + TRAP_IGNORE( ManipulateMapTileDataBaseL( lookupItem ) ); + TRAP_IGNORE( UpdateDatabaseL( NULL, + ids[i], ESourceCalendar, EEntryDeleted ) ); + + } + } +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::IsCalendarEntryValidL() +// ----------------------------------------------------------------------------- +// +TBool CMyLocationsEngine::IsCalendarEntryValidL( TUint32 aId ) +{ + return ( ( iCalView->FetchL( aId ) == NULL ) ? EFalse:ETrue ); +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::CalenderEntryAddedL() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::CalenderEntryAddedL(TCalChangeEntry aCalChangeEntry) +{ + __TRACE_CALLSTACK; + + TUint32 entryId=0; + entryId=aCalChangeEntry.iEntryId; + //create entry in the data base and maintain a fetching state. + TLookupItem lookupItem; + lookupItem.iUid = entryId ; + lookupItem.iSource = ESourceCalendar; + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + TRAP_IGNORE( iMaptileDatabase->CreateEntryL(lookupItem) ); + CCalEntry* calEntry = NULL; + calEntry = iCalView->FetchL( entryId ); + CleanupStack::PushL(calEntry); + TPtrC address(calEntry->LocationL()); + if (address.Length() > 0) + { + RequestMapTileImageL( address, ESourceCalendar, entryId , EChangeAdd ); + } + CleanupStack::PopAndDestroy(calEntry); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::CalenderEntryModifyL() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::CalenderEntryModifyL(TCalChangeEntry aCalChangeEntry) +{ + __TRACE_CALLSTACK; + TUint32 entryId = 0; + entryId = aCalChangeEntry.iEntryId; + TLookupItem lookupItem; + lookupItem.iSource = ESourceCalendar; + lookupItem.iUid = entryId; + CCalEntry* calEntry = NULL; + calEntry = iCalView->FetchL(entryId); + CleanupStack::PushL(calEntry); + if(iGeocodeUpdate->isGeocodeNotAvailable(entryId)) + { + TPtrC address(calEntry->LocationL()); + if (iMyLocationsDatabaseManager->CheckIfAddressChanged(address, entryId, + ESourceCalendar)) + { + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + TRAP_IGNORE( iMaptileDatabase->ReSetEntryL(lookupItem) ); + if (address.Length() > 0) + { + RequestMapTileImageL(address, ESourceCalendar, entryId , EChangeModify); + } + else + { + UpdateDatabaseL(NULL, entryId, ESourceCalendar, EEntryDeleted); + } + if ( lookupItem.iFilePath.Length() > 0 ) + { + iMaptileDatabase->DeleteMapTileL(lookupItem); + } + + } + } + CleanupStack::PopAndDestroy(calEntry); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::HandleDatabaseEventL() +// Callback that provides information about the contact database change event. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::HandleDatabaseEventL(TContactDbObserverEvent aEvent) +{ + __TRACE_CALLSTACK; + + //Forward the event for maptile fetching only if maptile plugin available + if( iMaptileGeocoderPluginAvailable ) + { + TriggerMaptileRequestL(aEvent); + } +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::TriggerMaptileRequestL() +// Process the contact address information for fetching maptile. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::TriggerMaptileRequestL(TContactDbObserverEvent& aEvent) +{ + __TRACE_CALLSTACK; + TLookupItem lookupItem; + lookupItem.iUid = aEvent.iContactId; + // If contact is deleted delete from mylocations db + if ( aEvent.iType == EContactDbObserverEventContactDeleted || aEvent.iType == EContactDbObserverEventOwnCardDeleted ) + { + //Delete the entries from maptile database + lookupItem.iSource = ESourceContactsPref; + TRAP_IGNORE( ManipulateMapTileDataBaseL(lookupItem)); + + lookupItem.iSource = ESourceContactsWork; + TRAP_IGNORE( ManipulateMapTileDataBaseL(lookupItem)); + + lookupItem.iSource = ESourceContactsHome; + TRAP_IGNORE( ManipulateMapTileDataBaseL(lookupItem)); + + // Delete entries from mylocation database + TRAP_IGNORE( UpdateDatabaseL( NULL, aEvent.iContactId, + ESourceContactsPref, EEntryDeleted )); + + TRAP_IGNORE( UpdateDatabaseL( NULL, aEvent.iContactId, + ESourceContactsHome, EEntryDeleted )); + + TRAP_IGNORE( UpdateDatabaseL( NULL, aEvent.iContactId, + ESourceContactsWork, EEntryDeleted ) ); + + MYLOCLOGSTRING("EContactDbObserverEventContactDeleted "); + return; + } + + //Get the contact item + iEventType = aEvent.iType; + QContact contactInfo = iContactManager->contact( aEvent.iContactId ); + CPosLandmark *preferedAddressLm = NULL; + CPosLandmark *workAddressLm = NULL; + CPosLandmark *homeAddressLm = NULL; + + TInt itemCount = 0; + + foreach ( QContactAddress address, contactInfo.details() ) + { + QStringList context = address.contexts(); + if ( context.isEmpty() ) // no context + { + preferedAddressLm = GetContactAddressDetailsLC( address ); + itemCount++; + } + else if ( context.first() == QContactAddress::ContextHome ) + { + homeAddressLm = GetContactAddressDetailsLC( address ); + itemCount++; + } + else if ( context.first() == QContactAddress::ContextWork ) + { + workAddressLm = GetContactAddressDetailsLC( address ); + itemCount++; + } + } + + switch (aEvent.iType) + { + case EContactDbObserverEventContactChanged: + case EContactDbObserverEventOwnCardChanged: + { + MYLOCLOGSTRING("EContactDbObserverEventContactChanged" ); + MYLOCLOGSTRING1("iMapTileRequestQueue.Count()-%d",iMapTileRequestQueue.Count() ); + + if (iMapTileRequestQueue.Count() > 0) + { + if (iMapTileRequestQueue[0]->iUId == aEvent.iContactId) + { + CleanupStack::PopAndDestroy( itemCount ); + MYLOCLOGSTRING("retrun from geolocation callback" ); + return; + } + } + + TBuf landmarkName; + GetContactName(aEvent.iContactId,landmarkName); + + // if default address available, update Mylocations. + lookupItem.iSource = ESourceContactsPref; + if (preferedAddressLm) + { + iMyLocationsDatabaseManager->UpdateEntryName( aEvent.iContactId, ESourceContactsPref, + landmarkName ); + MYLOCLOGSTRING("preferedAddressLm address changed" ); + + if ( iMyLocationsDatabaseManager->CheckIfAddressChanged(*preferedAddressLm, + aEvent.iContactId, ESourceContactsPref) ) + + { + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + TRAP_IGNORE( iMaptileDatabase->ReSetEntryL(lookupItem) ); + + RequestMapTileImageL(*preferedAddressLm, ESourceContactsPref, + aEvent.iContactId, iEventType ); + + if ( lookupItem.iFilePath.Length() > 0 ) + { + iMaptileDatabase->DeleteMapTileL(lookupItem); + } + + } + } + else + { + TRAP_IGNORE( UpdateDatabaseL( NULL, aEvent.iContactId, + ESourceContactsPref, EEntryDeleted )); + TRAP_IGNORE( ManipulateMapTileDataBaseL(lookupItem)); + + } + + // if home address available, update Mylocations. + lookupItem.iSource = ESourceContactsHome; + if (homeAddressLm) + { + iMyLocationsDatabaseManager->UpdateEntryName( aEvent.iContactId, ESourceContactsHome, + landmarkName ); + MYLOCLOGSTRING("homeAddressLm address changed" ); + if ( iMyLocationsDatabaseManager->CheckIfAddressChanged(*homeAddressLm, + aEvent.iContactId, ESourceContactsHome) ) + { + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + TRAP_IGNORE( iMaptileDatabase->ReSetEntryL(lookupItem) ) + //remove entry from databse + RequestMapTileImageL(*homeAddressLm, ESourceContactsHome, aEvent.iContactId, + iEventType); + if (lookupItem.iFilePath.Length() > 0) + { + iMaptileDatabase->DeleteMapTileL(lookupItem); + } + } + } + else + { + TRAP_IGNORE( UpdateDatabaseL( NULL, aEvent.iContactId, + ESourceContactsHome, EEntryDeleted )); + TRAP_IGNORE( ManipulateMapTileDataBaseL(lookupItem)); + + } + + + // if work address available, update Mylocations. + lookupItem.iSource = ESourceContactsWork; + if (workAddressLm) + { + iMyLocationsDatabaseManager->UpdateEntryName( aEvent.iContactId, ESourceContactsWork, + landmarkName ); + + MYLOCLOGSTRING("workAddressLm address changed" ); + if ( iMyLocationsDatabaseManager->CheckIfAddressChanged(*workAddressLm, + aEvent.iContactId, ESourceContactsWork) ) + { + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + TRAP_IGNORE( iMaptileDatabase->ReSetEntryL(lookupItem) ) + + RequestMapTileImageL(*workAddressLm, ESourceContactsWork, + aEvent.iContactId, iEventType); + if (lookupItem.iFilePath.Length() > 0) + { + iMaptileDatabase->DeleteMapTileL(lookupItem); + } + } + } + else + { + TRAP_IGNORE( UpdateDatabaseL( NULL, aEvent.iContactId, + ESourceContactsWork, EEntryDeleted )); + TRAP_IGNORE( ManipulateMapTileDataBaseL(lookupItem)); + + } + break; + } + case EContactDbObserverEventContactAdded: + { + TLookupItem lookupItem; + lookupItem.iUid = aEvent.iContactId; + lookupItem.iFilePath.Zero(); + lookupItem.iFetchingStatus = EMapTileFetchingInProgress; + + MYLOCLOGSTRING("EContactDbObserverEventContactAdded" ); + if (preferedAddressLm) + { + //create entry in the data base and maintain a fetching state. + lookupItem.iSource = ESourceContactsPref; + iMaptileDatabase->CreateEntryL(lookupItem); + RequestMapTileImageL(*preferedAddressLm, ESourceContactsPref, + aEvent.iContactId, iEventType); + } + if (homeAddressLm) + { + lookupItem.iSource = ESourceContactsHome; + iMaptileDatabase->CreateEntryL(lookupItem); + RequestMapTileImageL(*homeAddressLm, ESourceContactsHome, + aEvent.iContactId, iEventType); + } + if (workAddressLm) + { + lookupItem.iSource = ESourceContactsWork; + iMaptileDatabase->CreateEntryL(lookupItem); + RequestMapTileImageL(*workAddressLm, ESourceContactsWork, + aEvent.iContactId, iEventType); + } + break; + } + + } + + CleanupStack::PopAndDestroy( itemCount ); + +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::RequestMapTileImageL() +// Request to get maptiel +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::RequestMapTileImageL(const TDesC& aAddressDetails, + const TUidSourceType aAddressType, const TInt32 aUId ,const TInt aEventType) +{ + __TRACE_CALLSTACK; + SetFolderPathL(); + TBuf mImagePath; + mImagePath.Copy(imageFilePath); + + + CMapTileRequest* mapTileRequest = new (ELeave) CMapTileRequest; + + mapTileRequest->iAddressDetails = aAddressDetails.AllocL(); + mapTileRequest->iUId = aUId; + mapTileRequest->iAddressType = aAddressType; + mapTileRequest->iEventType = aEventType; + mapTileRequest->iImagePath.Zero(); + mapTileRequest->iImagePath.Copy(mImagePath); + + TInt error = KErrNone; + + if (iMapTileRequestQueue.Count() <= 0) + { + error = iMapTileRequestQueue.Append(mapTileRequest); + if ( KErrNone == error ) + { + error = RequestExecute(mapTileRequest); + } + } + else + { + MYLOCLOGSTRING("Added one more request to request queue" ); + error = iMapTileRequestQueue.Append(mapTileRequest); + } + + //If any error , free the allocated memory + if( error != KErrNone ) + { + delete mapTileRequest; + } + +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::RequestMapTileImageL() +// Request to get maptiel +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::RequestMapTileImageL(CPosLandmark& aLandmark, + const TUidSourceType aAddressType, const TInt32 aUId, + const TInt aEventType ) +{ + __TRACE_CALLSTACK; + + MYLOCLOGSTRING("check folder path existance!"); + SetFolderPathL(); + + + CMapTileRequest* mapTileRequest = new (ELeave) CMapTileRequest; + + mapTileRequest->iLandmarkInfo = CPosLandmark::NewL(aLandmark); + mapTileRequest->iUId = aUId; + mapTileRequest->iAddressType = aAddressType; + mapTileRequest->iEventType = aEventType; + mapTileRequest->iImagePath.Zero(); + mapTileRequest->iImagePath.Copy(imageFilePath); + MYLOCLOGSTRING1("RequestMapTileImageL() Queue count -%d",iMapTileRequestQueue.Count()); + + TInt error = KErrNone; + + if (iMapTileRequestQueue.Count() <= 0) + { + error = iMapTileRequestQueue.Append(mapTileRequest); + //error = RequestExecute(mapTileRequest); + if( KErrNone == error ) + { + //error = iMapTileRequestQueue.Append(mapTileRequest); + error = RequestExecute(mapTileRequest); + } + + } + else + { + MYLOCLOGSTRING("Added one more request to request queue" ); + error = iMapTileRequestQueue.Append(mapTileRequest); + } + + //If any error, free the memory allocated + if( error != KErrNone ) + { + delete mapTileRequest; + } +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::RequestExecute() +// Executes the maptile image processing request +// ----------------------------------------------------------------------------- +// +TInt CMyLocationsEngine::RequestExecute( CMapTileRequest* aMapTileRequest) +{ + __TRACE_CALLSTACK; + TInt errorCode = KErrNone; + MYLOCLOGSTRING1("Request address type - %d ",aMapTileRequest->iAddressType); + switch (aMapTileRequest->iAddressType) + { + case ESourceCalendar: + { + TRAP(errorCode,iMapTileInterface->GetGeoCodeFromAddressL(*(aMapTileRequest->iAddressDetails), + aMapTileRequest->iImagePath, this )); + break; + } + case ESourceContactsPref: + case ESourceContactsWork: + case ESourceContactsHome: + { + TRAP(errorCode, iMapTileInterface->GetGeoCodeFromAddressL(aMapTileRequest->iLandmarkInfo, + aMapTileRequest->iImagePath, this)); + break; + } + default: + break; + }; + + return errorCode; +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::GetContactAddressDetailsLC() +// get locatin details +// ----------------------------------------------------------------------------- +// +CPosLandmark* CMyLocationsEngine::GetContactAddressDetailsLC( + QContactAddress& aContactAddress ) +{ + __TRACE_CALLSTACK; + CPosLandmark *landmark = NULL; + + QString country = aContactAddress.country(); + QString locality = aContactAddress.locality(); + QString street = aContactAddress.street(); + QString region = aContactAddress.region(); + QString postalcode = aContactAddress.postcode(); + + landmark = CPosLandmark::NewL(); + CleanupStack::PushL(landmark); + + if ( !country.isEmpty() ) + { + TPtrC16 tempText(reinterpret_cast(country.utf16())); + landmark->SetPositionFieldL( EPositionFieldCountry, tempText ); + } + if ( !locality.isEmpty() ) + { + TPtrC16 tempText(reinterpret_cast(locality.utf16())); + landmark->SetPositionFieldL(EPositionFieldCity, tempText); + } + if ( !street.isEmpty() ) + { + TPtrC16 tempText(reinterpret_cast(street.utf16())); + landmark->SetPositionFieldL(EPositionFieldStreet, tempText); + } + if ( !postalcode.isEmpty() ) + { + TPtrC16 tempText(reinterpret_cast(postalcode.utf16())); + landmark->SetPositionFieldL(EPositionFieldPostalCode, tempText); + } + + return landmark; +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::MapsChangeType() +// Maps the source's change type to Mylocations entry change type +// ----------------------------------------------------------------------------- +// +TEntryChangeType CMyLocationsEngine::MapChangeType(TUidSourceType aSrcType, + TUint32 aChangeType) +{ + __TRACE_CALLSTACK;// return value + TEntryChangeType retVal = EEntryUnknown; + + switch (aSrcType) + { + // if source type is calendar + case ESourceCalendar: + { + switch( aChangeType ) + { + case EChangeAdd: + retVal = EEntryAdded; + break; + case EChangeDelete: + retVal = EEntryDeleted; + break; + case EChangeModify: + retVal = EEntryModified; + break; + } + break; + } + // if source type is contacts + case ESourceContactsPref: + case ESourceContactsWork: + case ESourceContactsHome: + { + switch (aChangeType) + { + case EContactDbObserverEventContactAdded: + retVal = EEntryAdded; + break; + case EContactDbObserverEventContactDeleted: + retVal = EEntryDeleted; + break; + case EContactDbObserverEventContactChanged: + retVal = EEntryModified; + break; + } + break; + } + + // if source type is landmarks or maps history + case ESourceLandmarks: + { + switch (aChangeType) + { + case EPosLmEventLandmarkCreated: + retVal = EEntryAdded; + break; + case EPosLmEventLandmarkDeleted: + retVal = EEntryDeleted; + break; + case EPosLmEventLandmarkUpdated: + retVal = EEntryModified; + break; + } + break; + } + case ESourceLandmarksCategory: + { + switch (aChangeType) + { + case EPosLmEventCategoryCreated: + retVal = EEntryAdded; + break; + } + } + break; + } + return retVal; +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::IsGeoCoordinateAvailable() +// Checks whether geocoordinate available in the contact detail. +// ----------------------------------------------------------------------------- +// +TBool CMyLocationsEngine::IsGeoCoordinateAvailable( QContact& aContact, + QString aAddressType, double& aLatitude , double& aLongitude ) + +{ + TBool geoFieldAvailable = EFalse; + QContactGeoLocation geoLocation; + + foreach( geoLocation, aContact.details() ) + { + if( !geoLocation.isEmpty()) + { + QStringList context = geoLocation.contexts(); + if ( context.isEmpty() ) + { + if ( aAddressType.isEmpty() ) + { + geoFieldAvailable = ETrue; + break; + } + } + else if( context.first() == aAddressType ) + { + geoFieldAvailable = ETrue; + break; + } + + } + + } + if( geoFieldAvailable ) + { + aLatitude = geoLocation.latitude(); + aLongitude = geoLocation.longitude(); + } + return geoFieldAvailable; +} + + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::RunL() +// Handles active object's request completion event. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::RunL() +{ + __TRACE_CALLSTACK; + switch (iLmEvent.iEventType) + { + case EPosLmEventLandmarkCreated: + case EPosLmEventLandmarkUpdated: + { + CPosLandmark* readLandmark = iLandmarkDb->ReadLandmarkLC( + iLmEvent.iLandmarkItemId); + + // update the entry in database. + UpdateDatabaseL( readLandmark, + iLmEvent.iLandmarkItemId, ESourceLandmarks, MapChangeType( + ESourceLandmarks, iLmEvent.iEventType ) ); + + CleanupStack::PopAndDestroy(readLandmark); + } + break; + case EPosLmEventLandmarkDeleted: + { + // delete the corresponding entries in mylocations database. + UpdateDatabaseL(NULL, + iLmEvent.iLandmarkItemId, ESourceLandmarks, EEntryDeleted); + } + break; + + } + + // start the change notifier again; + StartLandmarksChangeNotifier(); + +} +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::DoCancel() +// Implements cancellation of an outstanding request. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::DoCancel() +{ + __TRACE_CALLSTACK; + iLandmarkDb->CancelNotifyDatabaseEvent(); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::GeoCodefetchingCompleted() +// Handles the maptile fetching completion event and updates the maptile lookup db. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::GeoCodefetchingCompleted( TInt aErrCode, const TReal& aLatitude, + const TReal& aLongitude, const TDesC& aMapTilePath ) +{ + __TRACE_CALLSTACK; + MYLOCLOGSTRING1("GeoCodefetchingCompleted aErrCode - %d ",aErrCode); + MYLOCLOGSTRING1("iMapTileRequestQueue.Count - %d",iMapTileRequestQueue.Count()); + + TBuf8 buffer; + + if (iMapTileRequestQueue.Count() > 0) + { + MYLOCLOGSTRING1("No.of RequestQueue - %d",iMapTileRequestQueue.Count()); + + TLookupItem lookupItem; + lookupItem.iSource = iMapTileRequestQueue[0]->iAddressType; + lookupItem.iUid = iMapTileRequestQueue[0]->iUId; + + if (aErrCode == KErrNone) + { + UpdateGeoCodeToAppDataBase( aLatitude, aLongitude ); + + TBool flag = EFalse; + TRAP_IGNORE( flag = iMaptileDatabase->FindEntryByFilePathL(aMapTilePath) ); + if ( flag ) + { + MYLOCLOGSTRING1("%S - found in the DB",&aMapTilePath); + + + lookupItem.iFilePath.Copy(aMapTilePath); + lookupItem.iFetchingStatus = EMapTileFectchingCompleted; + TRAP_IGNORE( UpdateMaptileDatabaseL(iMapTileRequestQueue[0]->iEventType, lookupItem ) ); + //Publish the maptile status + if( iLastContactId == iMapTileRequestQueue[0]->iUId ) + { + buffer.Zero(); + buffer.Format( KMaptileStatusFormat, iLastContactId, lookupItem.iSource, lookupItem.iFetchingStatus ); + RProperty::Set( KMaptileStatusPublish, EMaptileStatusInteger, buffer ); + } + //Publish the maptile status ,if it was from calendar + if( iLastCalendarId == iMapTileRequestQueue[0]->iUId ) + { + buffer.Zero(); + buffer.Format( KMaptileStatusFormat, iLastCalendarId, lookupItem.iSource, lookupItem.iFetchingStatus ); + RProperty::Set( KMaptileStatusPublish, EMaptileStatusInteger, buffer ); + } + MYLOCLOGSTRING("UpdateMaptileDatabaseL handled"); + + //Process the pending maptile requests + ProcessNextMaptileRequest(); + + } + else + { + TRAPD( error, iMapTileInterface->GetMapTileL( aLatitude, aLongitude ) ); + if ( error != KErrNone ) + { + //Log error message + MYLOCLOGSTRING1("iMapTileInterface->GetMapTileL() status-%d",error); + MapTilefetchingCompleted(error, KNullDesC); + } + } + } + else + { + if ( aErrCode == KErrCouldNotConnect ) + { + lookupItem.iFetchingStatus = EMapTileFetchingNetworkError; + iMyLocationThreeAMTimer->StartTimer(); + + } + else + { + lookupItem.iFetchingStatus = EMapTileFetchingUnknownError; + } + TRAP_IGNORE( UpdateMaptileDatabaseL(iMapTileRequestQueue[0]->iEventType,lookupItem ) ); + + //Publish the maptile status + if( iLastContactId == iMapTileRequestQueue[0]->iUId ) + { + buffer.Zero(); + buffer.Format( KMaptileStatusFormat, iLastContactId, lookupItem.iSource, lookupItem.iFetchingStatus ); + RProperty::Set( KMaptileStatusPublish, EMaptileStatusInteger, buffer ); + } + //Publish the maptile status ,if it was from calendar + if( iLastCalendarId == iMapTileRequestQueue[0]->iUId ) + { + buffer.Zero(); + buffer.Format( KMaptileStatusFormat, iLastCalendarId, lookupItem.iSource, lookupItem.iFetchingStatus ); + RProperty::Set( KMaptileStatusPublish, EMaptileStatusInteger, buffer ); + } + + ProcessNextMaptileRequest(); + } + } +} + + + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::MyLocationThreeAMTimerExpiredL() +// Triggers the maptile fetching at 3.00 for the network failure cases. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::MyLocationThreeAMTimerExpiredL() +{ + //Forward the event for maptile fetching only if maptile plugin available + if( iMaptileGeocoderPluginAvailable ) + { + RArray iLookupItems; + iMaptileDatabase->FindEntriesByMapTileFetchingStateL((TUint32)EMapTileFetchingNetworkError, + iLookupItems); + for( TUint32 i = 0; i < iLookupItems.Count(); i++ ) + { + TLookupItem iItem = iLookupItems[i]; + switch( iItem.iSource ) + { + // Get the home address details + case ESourceContactsHome: + case ESourceContactsWork: + case ESourceContactsPref: + { + QContact contactInfo = iContactManager->contact( iItem.iUid ); + + CPosLandmark *addressLm = NULL; + + foreach ( QContactAddress address, contactInfo.details() ) + { + QStringList context = address.contexts(); + if ( ( context.isEmpty() && iItem.iSource == ESourceContactsPref ) + || + ( !context.isEmpty() && + ( ( context.first() == QContactAddress::ContextHome && iItem.iSource == ESourceContactsHome ) || + ( context.first() == QContactAddress::ContextWork && iItem.iSource == ESourceContactsWork ) ) ) ) + { + // Get the default/prefered address details + addressLm = GetContactAddressDetailsLC( address ); + if( addressLm ) + { + RequestMapTileImageL( *addressLm, + ( TUidSourceType )iItem.iSource, iItem.iUid, EContactDbObserverEventContactChanged ); + CleanupStack::PopAndDestroy( addressLm ); + break; + } + } + } + } + break; + + case ESourceCalendar: + { + CCalEntry* calEntry = NULL; + calEntry = iCalView->FetchL(iItem.iUid); + if( calEntry ) + { + CleanupStack::PushL(calEntry); + TPtrC address(calEntry->LocationL()); + if(address.Length()>0) + { + RequestMapTileImageL( address, ESourceCalendar, iItem.iUid , EChangeModify); + } + CleanupStack::PopAndDestroy(calEntry); + } + else + { + iMaptileDatabase->DeleteEntryL( iItem ); + } + } + break; + + default: + break; + } + }// end for + } +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::MapTilefetchingCompleted() +// Handles the maptile fetching completion event and updates the maptile lookup db. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::MapTilefetchingCompleted(TInt aErrCode, + const TDesC& aMapTilePath) +{ + __TRACE_CALLSTACK; + MYLOCLOGSTRING1("MapTilefetchingCompleted aErrCode - %d ",aErrCode); + MYLOCLOGSTRING1("iMapTileRequestQueue.Count - %d",iMapTileRequestQueue.Count()); + + if ( iMapTileRequestQueue.Count() > 0 ) + { + + MYLOCLOGSTRING1("No.of RequestQueue - %d",iMapTileRequestQueue.Count()); + + TLookupItem lookupItem; + lookupItem.iSource = iMapTileRequestQueue[0]->iAddressType; + lookupItem.iUid = iMapTileRequestQueue[0]->iUId; + + if ( aErrCode == KErrNone ) + { + CreateMultipleMaptiles( aMapTilePath ); + lookupItem.iFilePath.Copy(aMapTilePath); + lookupItem.iFetchingStatus = EMapTileFectchingCompleted; + + } + else if ( aErrCode == KErrCouldNotConnect ) + { + lookupItem.iFetchingStatus = EMapTileFetchingNetworkError; + iMyLocationThreeAMTimer->StartTimer(); + + } + else + { + lookupItem.iFetchingStatus = EMapTileFetchingUnknownError; + } + + TRAP_IGNORE( UpdateMaptileDatabaseL( iMapTileRequestQueue[0]->iEventType,lookupItem ) ); + + // if the source type is contacts, update the contact name into the locationdatalookupdb. + // This has to be done, because there is a possibility that the user might change the + // contact name between geocodefetchingcomplete and maptilefetchingcomplete. + if( iMapTileRequestQueue[0]->iAddressType == ESourceContactsPref || + iMapTileRequestQueue[0]->iAddressType == ESourceContactsHome || + iMapTileRequestQueue[0]->iAddressType == ESourceContactsWork ) + { + TBuf landmarkName; + GetContactName( iMapTileRequestQueue[0]->iUId, landmarkName ); + + iMyLocationsDatabaseManager->UpdateEntryName( + iMapTileRequestQueue[0]->iUId, ESourceContactsPref, landmarkName ); + iMyLocationsDatabaseManager->UpdateEntryName( + iMapTileRequestQueue[0]->iUId, ESourceContactsHome, landmarkName ); + iMyLocationsDatabaseManager->UpdateEntryName( + iMapTileRequestQueue[0]->iUId, ESourceContactsWork, landmarkName ); + } + + //Publish the maptile status , if it was from contact + if( iLastContactId == iMapTileRequestQueue[0]->iUId ) + { + TBuf8 buffer; + buffer.Format( KMaptileStatusFormat, iLastContactId, lookupItem.iSource, lookupItem.iFetchingStatus ); + RProperty::Set( KMaptileStatusPublish, EMaptileStatusInteger, buffer ); + } + //Publish the maptile status ,if it was from calendar + if( iLastCalendarId == iMapTileRequestQueue[0]->iUId ) + { + TBuf8 buffer; + buffer.Format( KMaptileStatusFormat, iLastCalendarId, lookupItem.iSource, lookupItem.iFetchingStatus ); + RProperty::Set( KMaptileStatusPublish, EMaptileStatusInteger, buffer ); + } + } + + ProcessNextMaptileRequest(); +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::ProcessNextMaptileRequest() +// Process the next maptile request if any pending. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::ProcessNextMaptileRequest() +{ + //Process the next request if it is pending + if ( iMapTileRequestQueue.Count() > 0) + { + //Remove the current top request + delete iMapTileRequestQueue[0]; + iMapTileRequestQueue.Remove(0); + iMapTileRequestQueue.Compress(); + + //Process the next request in queue + MYLOCLOGSTRING1("MapTile fetch completed request-%d",iMapTileRequestQueue.Count()); + for (TInt cnt = 0; cnt < iMapTileRequestQueue.Count(); cnt++) + { + if ( KErrNone == RequestExecute( iMapTileRequestQueue[0]) ) + { + break; + } + else + { + //Process the next request in queue + ProcessNextMaptileRequest(); + + } + } + } + else + { + MYLOCLOGSTRING("MapTile fetch completed no request in queue"); + iMapTileRequestQueue.Reset(); + } +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::HandleMaptileDatabaseL() +// Handle maptile database(find/create/update/delete). +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::UpdateMaptileDatabaseL( + TInt aEventType, TLookupItem& aLookupItem) +{ + __TRACE_CALLSTACK; + if (aEventType == EContactDbObserverEventContactChanged || aEventType + == EChangeModify || aEventType == EContactDbObserverEventContactAdded || + aEventType == EChangeAdd ) + { + + if (iMaptileDatabase->FindEntryL(aLookupItem)) + { + iMaptileDatabase->UpdateEntryL(aLookupItem); + } + else + { + iMaptileDatabase->CreateEntryL(aLookupItem); + } + } + if (aLookupItem.iFetchingStatus == EMapTileFetchingUnknownError + || aLookupItem.iFetchingStatus == EMapTileFetchingNetworkError) + { + TRAP_IGNORE( UpdateDatabaseL( NULL, + aLookupItem.iUid, aLookupItem.iSource, EEntryDeleted ) ); + + } + else + { + TPtrC8 ptr(reinterpret_cast(MAPTILE_IMAGE_HURRIGANES)); + HBufC* buffer = NULL; + buffer=HBufC::NewLC(ptr.Length()); + buffer->Des().Copy(ptr); + if(buffer) + { + aLookupItem.iFilePath.Append(*buffer); + } + CleanupStack::PopAndDestroy(buffer); + iMyLocationsDatabaseManager->UpdateMapTilePath(aLookupItem.iUid, + aLookupItem.iSource, aLookupItem.iFilePath); + } +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::RestGeoCodeCompleted() +// observed when rest geo codeing completed. +// started lat and lon field updation into contact db. +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::UpdateGeoCodeToAppDataBase( TReal aLatitude, TReal aLongitude ) +{ + __TRACE_CALLSTACK; + + MYLOCLOGSTRING1("No. of iMapTileRequestQueue - %d",iMapTileRequestQueue.Count()); + if (iMapTileRequestQueue.Count() > 0) + { + switch (iMapTileRequestQueue[0]->iAddressType) + { + //TODO: + case ESourceCalendar: + { + iGeocodeUpdate->updateGeocodeToCalenderDB(iMapTileRequestQueue[0]->iUId, + aLatitude,aLongitude); + CPosLandmark *landmark = NULL; + landmark = iMapTileInterface->GetLandMarkDetails(); + if (NULL != landmark) + { + TRAP_IGNORE( landmark->SetPositionFieldL(EPositionFieldComment, + iMapTileRequestQueue[0]->iAddressDetails->Des() ) ); + TRAP_IGNORE( UpdateDatabaseL( landmark, iMapTileRequestQueue[0]->iUId, + ESourceCalendar, + MapChangeType( ESourceCalendar, iMapTileRequestQueue[0]->iEventType ) ) ); + } + MYLOCLOGSTRING("Geo-codinate updated to calender db"); + break; + } + case ESourceContactsPref: + case ESourceContactsWork: + case ESourceContactsHome: + { + iGeocodeUpdate->updateGeocodeToContactDB( + iMapTileRequestQueue[0]->iUId, + iMapTileRequestQueue[0]->iAddressType, aLatitude, + aLongitude); + TBuf landmarkName; + GetContactName(iMapTileRequestQueue[0]->iUId,landmarkName); + //Update mylocation database + iMapTileRequestQueue[0]->iLandmarkInfo->SetLandmarkNameL( landmarkName ); + TRAP_IGNORE( UpdateDatabaseL( + iMapTileRequestQueue[0]->iLandmarkInfo, + iMapTileRequestQueue[0]->iUId, + iMapTileRequestQueue[0]->iAddressType, + MapChangeType( + static_cast( iMapTileRequestQueue[0]->iAddressType ), + iMapTileRequestQueue[0]->iEventType ))); + + MYLOCLOGSTRING("Geo-codinate updated to contact db"); + break; + } + }; + } + +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::GetContactName() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::GetContactName( TInt32 aUId,TDes& aName) +{ + QContact contactInfo = iContactManager->contact( aUId ); + QContactName name = contactInfo.detail( QContactName::DefinitionName ); + QString firstName = name.firstName(); + QString lastName = name.lastName(); + QString fullName(""); + + if( lastName.isEmpty() ) + { + fullName = firstName; + } + else + { + if( !firstName.isEmpty() ) + { + fullName = firstName + KSpace; + } + fullName = fullName + lastName; + } + + aName.Copy( reinterpret_cast(fullName.utf16()) ); +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::UpdateDatabaseL() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::UpdateDatabaseL( CPosLandmark* aLandmark, const TUint32 aUid, + const TUint32 aSourceType, const TEntryChangeType aChangeType ) +{ + __TRACE_CALLSTACK; + if(IsActive()) + { + Cancel(); + } + iMyLocationsDatabaseManager->UpdateDatabaseL( aLandmark, aUid, + aSourceType, aChangeType ); + if( aSourceType != ESourceLandmarks ) + { + StartLandmarksChangeNotifier(); + } + +} + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::ManipulateMapTileDataBaseL() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::ManipulateMapTileDataBaseL(TLookupItem& aLookupItem) +{ + __TRACE_CALLSTACK; + TBool entryAvailable=EFalse; + entryAvailable = iMaptileDatabase->FindEntryL(aLookupItem); + iMaptileDatabase->DeleteEntryL(aLookupItem); + if (entryAvailable) + { + iMaptileDatabase->DeleteMapTileL(aLookupItem); + } +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::CreateMultipleMaptiles() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::CreateMultipleMaptiles( const TDesC& aMaptilePath ) +{ + __TRACE_CALLSTACK; + QString filePath = QString::fromUtf16( aMaptilePath.Ptr(), aMaptilePath.Length() ); + + //Portrait image , common for contacts/calendar/context menu + CropAndSaveImage( filePath, + MaptilePortraitWidth, + MaptilePortraitHeight, + QString(), + QString( MAPTILE_IMAGE_PORTRAIT ) ); + + //Landscape image for contacts + CropAndSaveImage( filePath, + MaptileContactLandscapeWidth, + MaptileContactLandscapeHeight, + QString( MAPTILE_IMAGE_CONTACT ), + QString( MAPTILE_IMAGE_LANDSCAPE ) ); + + //Ladscape image for calendar + CropAndSaveImage( filePath, + MaptileCalendarLandscapeWidth, + MaptileCalendarLandscapeHeight, + QString( MAPTILE_IMAGE_CALENDAR ), + QString( MAPTILE_IMAGE_LANDSCAPE ) ); + + //Image for hurriganes + CropAndSaveImage( filePath, + MaptileHurriganesWidth, + MaptileHurriganesHeight, + QString( MAPTILE_IMAGE_HURRIGANES ), + QString() ); + QFile file(filePath); + file.remove(); +} + + +// ----------------------------------------------------------------------------- +// CMyLocationsEngine::CropAndSaveImage() +// ----------------------------------------------------------------------------- +// +void CMyLocationsEngine::CropAndSaveImage( QString filePath, int width, + int height, QString appType, QString orientationType ) +{ + __TRACE_CALLSTACK; + QImage SourcePNG( filePath ); + QImage sourcePixmap( SourcePNG.convertToFormat(QImage::Format_Indexed8)); + QImage targetPixmap( sourcePixmap.copy( + ( MapTileWidth - width )/2, + ( MapTileHeight - height )/2 , + width, + height ) ); + + QString targetImage; + targetImage.append( filePath ); + targetImage.append( appType ); + targetImage.append( orientationType ); + targetPixmap.save( targetImage, MAPTILE_IMAGE_TYPE ); + +} + +//End of file +