--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitymodules/SeCon/services/csc/src/sconsyncservice.cpp Wed Sep 01 12:20:56 2010 +0100
@@ -0,0 +1,505 @@
+/*
+* 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: CSConSyncService implementation.
+*
+*/
+
+
+// Includes
+#include <centralrepository.h>
+#include <seconsdkcrkeys.h>
+
+#include <swi/sisregistryentry.h> // for searching app name from installer
+#include <swi/sisregistrypackage.h>
+#include <swi/sisregistrysession.h>
+#include <javaregistryincludes.h>
+using namespace Java;
+
+#include "sconsyncservice.h"
+#include "capability.h"
+#include "debug.h"
+
+// Constants
+const TInt KDsAppUi = 0x101F6DE4; // NSmlDSSync.exe
+const TSmlDataProviderId KCalendarId = 0x101f6dde;
+const TSmlDataProviderId KContactsId = 0x101f6ddd;
+const TSmlDataProviderId KSmsId = 0x10206b5c;
+const TSmlDataProviderId KBookmarkId = 0x102751ba;
+
+const TInt KDateFormatLength(16);
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::NewLC()
+// -----------------------------------------------------------------------------
+//
+CSConSyncService* CSConSyncService::NewLC()
+ {
+ TRACE_FUNC_ENTRY;
+ CSConSyncService* self = new (ELeave) CSConSyncService();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ TRACE_FUNC_EXIT;
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::CSConSyncService()
+// -----------------------------------------------------------------------------
+//
+CSConSyncService::CSConSyncService()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::~CSConSyncService()
+// -----------------------------------------------------------------------------
+//
+CSConSyncService::~CSConSyncService()
+ {
+ TRACE_FUNC_ENTRY;
+ if ( iApaSessionConnected )
+ {
+ iApaSession.Close();
+ }
+ if ( iSyncSessionOpened )
+ {
+ iSyncSession.Close();
+ }
+ delete iRepository;
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::ConstructL()
+ {
+ iRepository = CRepository::NewL( KCRUidSecon );
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::GetSolutionL()
+// Populate SolutionInfo according to content type.
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::GetSolutionL( const TUint aSeconContentType,
+ TSConSolutionInfo& aSolutionInfo )
+ {
+ TRACE_FUNC_ENTRY;
+ TInt appUid;
+ User::LeaveIfError( iRepository->Get( aSeconContentType, appUid ));
+ LOGGER_WRITE_2( "repository readed ok, uid: %d, hex:%x", appUid, appUid );
+
+ aSolutionInfo.iUid = appUid;
+ if ( aSolutionInfo.iUid == KDsAppUi )
+ {
+ // read profile name
+ LOGGER_WRITE( "Search correct profile" );
+ GetLastUsedProfileNameL( aSolutionInfo.iSolutionName,
+ aSolutionInfo.iTime, ProviderId( aSeconContentType ) );
+ }
+ else if ( aSolutionInfo.iUid != 0 )
+ {
+ LOGGER_WRITE( "Search correct application name" );
+ TUid appUid = {aSolutionInfo.iUid};
+ GetApplicationCaptionL( aSolutionInfo.iSolutionName, appUid );
+
+ // get solution timestamp
+ TBuf<KDateFormatLength> timeBuffer;
+ // Timestamp is stored always in next to Uid value on cenrep
+ TInt err = iRepository->Get( aSeconContentType+1, timeBuffer );
+
+ LOGGER_WRITE_1( "iRepository->Get(time) err: %d", err );
+ if ( err == KErrNone )
+ {
+ err = ParseTimestamp( aSolutionInfo.iTime, timeBuffer );
+ LOGGER_WRITE_1( "ParseTimestamp err: %d", err );
+ }
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::ProviderId()
+// Return correct providerId according to content type.
+// -----------------------------------------------------------------------------
+//
+TSmlDataProviderId CSConSyncService::ProviderId( const TUint32 aSeconContentType ) const
+ {
+ TSmlDataProviderId providerId(KErrNotFound);
+ switch (aSeconContentType)
+ {
+ case KSeconCalendarUid:
+ providerId = KCalendarId;
+ break;
+ case KSeconContactsUid:
+ providerId = KContactsId;
+ break;
+ case KSeconSmsUid:
+ providerId = KSmsId;
+ break;
+ case KSeconBookmarkUid:
+ providerId = KBookmarkId;
+ break;
+ default:
+ LOGGER_WRITE_1( "Invalid content type: %d", aSeconContentType );
+ }
+ return providerId;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::ParseTimestamp()
+// Parses timestamp to TTime format
+// -----------------------------------------------------------------------------
+//
+TInt CSConSyncService::ParseTimestamp( TTime& aTime, const TDesC& aTimestamp ) const
+ {
+ // timestamp must be in following format:
+ // YYYYMMDDTHHMMSSZ
+ // MM=1..12, DD=1..number of days in month, HH=0..23, MM;SS=0..59
+ // Example 20071224T162215Z = 24.12.2007, 16:22:15 UTC time
+
+ if ( aTimestamp.Length() != KDateFormatLength )
+ {
+ LOGGER_WRITE_1( "aTimestamp.Length(): %d", aTimestamp.Length() );
+ return KErrArgument;
+ }
+
+ TPtrC temp;
+ temp.Set(aTimestamp.Ptr());
+
+ TLex lex(temp.Mid(0,4));
+ TInt year;
+ TInt month;
+ TInt day;
+ TInt hour;
+ TInt minute;
+ TInt second;
+ TInt err = lex.Val( year );
+ if (err != KErrNone) return err;
+
+ lex = temp.Mid(4,2);
+ err = lex.Val( month );
+ if ( err != KErrNone) return err;
+ month--;
+
+ lex = temp.Mid(6,2);
+ err = lex.Val( day );
+ if (err != KErrNone) return err;
+ day--;
+
+ lex = temp.Mid(9,2);
+ err = lex.Val( hour );
+ if (err != KErrNone) return err;
+
+ lex = temp.Mid(11,2);
+ err = lex.Val( minute );
+ if (err != KErrNone) return err;
+
+ lex = temp.Mid(13,2);
+ err = lex.Val( second );
+ if (err != KErrNone) return err;
+
+ TDateTime parsedTime;
+ err = parsedTime.Set(year, (TMonth)month, day, hour, minute, second, 0);
+ if (err != KErrNone) return err;
+
+ aTime = parsedTime;
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::GetApplicationCaptionL()
+// Get application caption.
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::GetApplicationCaptionL( TDes& aCaption, const TUid aAppUid )
+ {
+ TRACE_FUNC_ENTRY;
+
+ TInt err(KErrNotReady);
+ // connect to RApaLsSession, if not yet ready
+ if ( !iApaSessionConnected )
+ {
+ err = iApaSession.Connect();
+ if ( err == KErrNone )
+ {
+ iApaSessionConnected = ETrue;
+ }
+ }
+
+ // Get application caption using RApaLsSession::GetAppInfo
+ TApaAppInfo appInfo;
+ if ( iApaSessionConnected )
+ {
+ err = iApaSession.GetAppInfo( appInfo ,aAppUid );
+ }
+
+ LOGGER_WRITE_1( "GetAppInfo err: %d", err );
+ if ( err == KErrNone )
+ {
+ aCaption = appInfo.iCaption;
+ }
+ else
+ {
+ // Caption does not exist, search application name from installer
+ GetInstPackageCaptionL( aCaption, aAppUid );
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::GetInstPackageCaptionL()
+// Search UID from installed applications, return app caption
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::GetInstPackageCaptionL( TDes& aCaption, const TUid aPackageUid )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE("Name not found, search from installer");
+ // Search application name from Installer.
+ Swi::RSisRegistrySession sisRegistry;
+ User::LeaveIfError( sisRegistry.Connect() );
+ CleanupClosePushL( sisRegistry );
+
+ //Check if uid belongs to SIS package
+ if( sisRegistry.IsInstalledL( aPackageUid ) )
+ {
+ LOGGER_WRITE("SIS package found");
+ Swi::RSisRegistryEntry entry;
+ CleanupClosePushL(entry);
+ User::LeaveIfError( entry.Open( sisRegistry, aPackageUid ) );
+ aCaption.Copy( *entry.PackageNameL() );
+ CleanupStack::PopAndDestroy( &entry );
+ }
+ else
+ {
+ // not sis app, might be java app.
+ LOGGER_WRITE("SIS package not found");
+ CJavaRegistry* javaRegistry = CJavaRegistry::NewLC( );
+ TBool entryExist = javaRegistry->RegistryEntryExistsL( aPackageUid );
+ if ( entryExist )
+ {
+ CJavaRegistryEntry* entry = javaRegistry->RegistryEntryL( aPackageUid );
+ if ( entry )
+ {
+ aCaption.Copy( entry->Name() );
+ delete entry;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( javaRegistry );
+ }
+
+ CleanupStack::PopAndDestroy( &sisRegistry );
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::GetLastUsedProfileNameL()
+// Gets last used profile for selected provider
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::GetLastUsedProfileNameL( TDes& aProfileName, TTime& aTime,
+ const TSmlDataProviderId& aDataProviderId )
+ {
+ TRACE_FUNC_ENTRY;
+ if ( !iSyncSessionOpened )
+ {
+ iSyncSession.OpenL();
+ iSyncSessionOpened = ETrue;
+ }
+ RArray<TSmlProfileId> profiles;
+ CleanupClosePushL( profiles );
+ iSyncSession.ListProfilesL(profiles, ESmlDataSync );
+ TSmlProfileId lastSyncProfile(KErrNotFound);
+ TTime lastSyncTime(0);
+ LOGGER_WRITE_1( "Profiles count: %d", profiles.Count() );
+ for (TInt i=0; i<profiles.Count(); i++)
+ {
+ TTime syncTime(0);
+ GetLastSyncTimeL( syncTime, profiles[i], aDataProviderId );
+ if ( syncTime.Int64() != 0 && syncTime > lastSyncTime )
+ {
+ LOGGER_WRITE_1( "New record, profile: %d",profiles[i]);
+ lastSyncTime = syncTime;
+ lastSyncProfile = profiles[i];
+ }
+ }
+ CleanupStack::PopAndDestroy( &profiles );
+ LOGGER_WRITE_1( "lastSyncProfile: %d", lastSyncProfile );
+ if ( lastSyncProfile != KErrNotFound )
+ {
+ aTime = lastSyncTime;
+ RSyncMLDataSyncProfile syncProfile;
+ syncProfile.OpenL( iSyncSession, lastSyncProfile, ESmlOpenRead );
+ TPtrC displayName = syncProfile.DisplayName();
+ aProfileName.Copy( displayName );
+ syncProfile.Close();
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::GetLastSyncTimeL()
+// Gets last sync time for certain profile and provider.
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::GetLastSyncTimeL( TTime& aTime, const TSmlProfileId aSyncProfileId,
+ const TSmlDataProviderId aDataProviderId )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1( "aSyncProfileId: %d", aSyncProfileId );
+ LOGGER_WRITE_1( "aDataProviderId: 0x%08x", aDataProviderId );
+ if ( !iSyncSessionOpened )
+ {
+ LOGGER_WRITE("iSyncSession is not opened, Leave!");
+ User::Leave( KErrNotReady );
+ }
+
+ RSyncMLDataSyncProfile syncProfile;
+ syncProfile.OpenL( iSyncSession, aSyncProfileId, ESmlOpenRead );
+ CleanupClosePushL( syncProfile );
+ LOGGER_WRITE( "syncProfile opened OK" );
+
+ TSmlTaskId providerTask;
+ GetProviderTaskL( providerTask, syncProfile, aDataProviderId );
+ if ( providerTask != KErrNone )
+ {
+ RSyncMLHistoryLog historyLog;
+ historyLog.OpenL( iSyncSession, aSyncProfileId );
+ CleanupClosePushL( historyLog );
+ historyLog.SortEntries(CSyncMLHistoryEntry::ESortByTime);
+ LOGGER_WRITE_1( "historyLog.Count: %d", historyLog.Count() );
+ const CSyncMLHistoryJob* historyJob = LatestHistoryJob( historyLog, providerTask );
+ if ( historyJob )
+ {
+ aTime = historyJob->TimeStamp();
+#ifdef _DEBUG
+ TDateTime timeStamp = historyJob->TimeStamp().DateTime();
+ _LIT(KDateFormat, " (%04d%02d%02dT%02d%02d%02d)");
+ const TInt KDateFormatLength(20);
+ TBuf<KDateFormatLength> tempdate;
+ tempdate.Format(KDateFormat, timeStamp.Year(), timeStamp.Month()+1, timeStamp.Day()+1,
+ timeStamp.Hour(), timeStamp.Minute(), timeStamp.Second());
+ LOGGER_WRITE_1("history found, TimeStamp: %S", &tempdate);
+#endif
+ }
+
+ CleanupStack::PopAndDestroy( &historyLog );
+ }
+ CleanupStack::PopAndDestroy( &syncProfile );
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::GetProviderTaskL()
+// Gets provider task id from profile
+// -----------------------------------------------------------------------------
+//
+void CSConSyncService::GetProviderTaskL( TSmlTaskId& aProviderTask,
+ RSyncMLDataSyncProfile& aSyncProfile,
+ const TSmlDataProviderId aDataProviderId ) const
+ {
+ TRACE_FUNC_ENTRY;
+ aProviderTask = KErrNotFound;
+
+ RArray<TSmlTaskId> tasks;
+ CleanupClosePushL( tasks );
+
+ aSyncProfile.ListTasksL( tasks );
+ LOGGER_WRITE_1( "tasks.Count: %d", tasks.Count() );
+
+ for ( TInt i=0; i<tasks.Count() && aProviderTask==KErrNotFound; i++ )
+ {
+ RSyncMLTask syncTask;
+ syncTask.OpenL( aSyncProfile, tasks[i] );
+ if ( syncTask.DataProvider() == aDataProviderId )
+ {
+ LOGGER_WRITE_1( "dataprovider task found, taskId: %d", tasks[i] );
+ aProviderTask = tasks[i];
+ }
+ syncTask.Close();
+ }
+
+ CleanupStack::PopAndDestroy( &tasks );
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CSConSyncService::LatestHistoryJob()
+// Gets latest historyJob where task is correct.
+// -----------------------------------------------------------------------------
+//
+ const CSyncMLHistoryJob* CSConSyncService::LatestHistoryJob(
+ RSyncMLHistoryLog& aHistoryLog, TInt aTaskId ) const
+ {
+ TRACE_FUNC_ENTRY;
+
+ TInt count = aHistoryLog.Count();
+ if ( count == 0 )
+ {
+ LOGGER_WRITE( "profile has no history job" );
+ TRACE_FUNC_EXIT;
+ return NULL; // profile has no history job
+ }
+
+ aHistoryLog.SortEntries(CSyncMLHistoryEntry::ESortByTime);
+
+ // try to find latest sync job (start from last array entry)
+
+ for ( TInt i=count-1; i>=0; i-- )
+ {
+ const CSyncMLHistoryEntry& entry = aHistoryLog[i];
+ const CSyncMLHistoryJob* jobEntry = CSyncMLHistoryJob::DynamicCast(&entry);
+ if ( jobEntry )
+ {
+ if ( TaskExist(jobEntry, aTaskId) )
+ {
+ LOGGER_WRITE( "history job found" );
+ TRACE_FUNC_EXIT;
+ return jobEntry;
+ }
+ }
+ }
+ LOGGER_WRITE( "history job not found" );
+ TRACE_FUNC_EXIT;
+ return NULL;
+ }
+
+ // -----------------------------------------------------------------------------
+ // CSConSyncService::TaskExist()
+ // Returns ETrue if task exists in HistoryJob.
+ // -----------------------------------------------------------------------------
+ //
+TBool CSConSyncService::TaskExist( const CSyncMLHistoryJob* aHistoryJob, TInt aTaskId ) const
+ {
+ TRACE_FUNC_ENTRY;
+ TInt taskCount = aHistoryJob->TaskCount();
+ for ( TInt i=0; i<taskCount; i++ )
+ {
+ const CSyncMLHistoryJob::TTaskInfo& taskInfo = aHistoryJob->TaskAt(i);
+
+ if ( taskInfo.iTaskId == aTaskId )
+ {
+ LOGGER_WRITE( "task exists." );
+ TRACE_FUNC_EXIT;
+ return ETrue;
+ }
+ }
+ TRACE_FUNC_EXIT;
+ return EFalse;
+ }
+