diff -r 79859ed3eea9 -r 919f36ff910f webengine/widgetregistry/Server/src/WidgetRegistry.cpp --- a/webengine/widgetregistry/Server/src/WidgetRegistry.cpp Tue Aug 31 16:17:46 2010 +0300 +++ b/webengine/widgetregistry/Server/src/WidgetRegistry.cpp Wed Sep 01 12:28:30 2010 +0100 @@ -29,10 +29,11 @@ #include #include #include +#include "WidgetMMCHandler.h" #include #include "UidAllocator.h" #if defined( BRDO_WRT_SECURITY_MGR_FF ) -#include +#include #endif #include @@ -62,6 +63,8 @@ "a:\\private\\10282f06\\WidgetEntryStore.dat" ); _LIT( KWidgetEntryStoreXmlFile, "a:\\private\\10282f06\\WidgetEntryStore.xml" ); +_LIT( KCWRTWidgetEntryStoreXmlFile, + "c:\\private\\10282f06\\CWRTWidgetEntryStore.xml" ); _LIT( KWidgetEntryStoreXmlTempFile, "a:\\private\\10282f06\\WidgetEntryStoreTemp.xml" ); _LIT( KWidgetDirFile, "widget_lproj.xml" ); @@ -133,7 +136,7 @@ // ============================================================================ // -static void NotifyWidgetAltered() +void CWidgetRegistry::NotifyWidgetAltered() { const TUid KMyPropertyCat = { 0x10282E5A }; enum TMyPropertyKeys { EMyPropertyAltered = 110 }; @@ -168,6 +171,7 @@ iWidgetInstallPath( KWidgetInstallPath ), iRegistryBinaryFileName( KWidgetEntryStoreBinaryFile ), iRegistryXmlFileName( KWidgetEntryStoreXmlFile ), + iRegistryCWRTXmlFileName( KCWRTWidgetEntryStoreXmlFile ), iRegistryXmlTempFileName( KWidgetEntryStoreXmlTempFile ), iPolicyId( 0 ) { @@ -183,13 +187,14 @@ CWidgetRegistry::~CWidgetRegistry() { iEntries.ResetAndDestroy(); + iOldEntries.ResetAndDestroy(); iUsedUids.Close(); // iFs not owned iAppArch.Close(); delete iInstaller; iLangDirList.ResetAndDestroy(); + delete iMMCHandler; delete iXmlProcessor; - delete iApaAppListNotifier; iFs.Close(); LOG_DESTRUCT; } @@ -250,7 +255,8 @@ LOG1( "ConstructL internalize done, registry count %d", iEntries.Count() ); LOG_CLOSE; - iApaAppListNotifier = CApaAppListNotifier::NewL(this,CActive::EPriorityStandard); + iMMCHandler = CWidgetMMCHandler::NewL( *this, iFs ); + iMMCHandler->Start(); } // ============================================================================ @@ -333,7 +339,7 @@ } } #else - iPolicyId = KErrNotSupported; + iPolicyId = KErrNotSupported; #endif return iPolicyId; } @@ -384,6 +390,29 @@ } // ============================================================================ +// CWidgetRegistry::GetWidgetOldEntry() +// Get the widget entry from iOldEntrys array +// +// @since 3.1 +// ============================================================================ +// +TInt CWidgetRegistry::GetWidgetOldEntry( + const TUid& aUid, + CWidgetEntry*& aEntry) const + { + for(TInt i = 0;i < iOldEntries.Count();i++) + { + CWidgetEntry* entry = iOldEntries[i]; + if ( TUid::Uid( (*entry)[EUid] ) == aUid ) + { + aEntry = entry; + return i; + } + } + return -1; + } + +// ============================================================================ // CWidgetRegistry::GetWidgetEntry() // Get the widget entry // @@ -527,9 +556,15 @@ // internal dirty flag, will be copied to arg dirty flag at // end if no leave occurs TBool dirtyFlag = EFalse; - - // empty the registry - iEntries.ResetAndDestroy(); + + // Copy the entries so we are able to use them later + // iOldEntries owns the data and is responcible to ResetAndDestroy() + for ( TInt i = 0; i < iEntries.Count(); i++ ) + { + iOldEntries.Append( iEntries[i] ); + } + // Only reset here as the iOldEntries owns the data + iEntries.Reset(); iUsedUids.Reset(); CleanupClosePushL( appArchList ); @@ -549,11 +584,15 @@ // UIDs already known to app arch be reserved. for ( TInt i = 0; i < appArchList.Count(); i++ ) { - if ( KErrNone != iUsedUids.Append( (appArchList)[i] ) ) + // Do not maintain the list of used CWRT widget UIDs + if ( !TUidAllocator::IsCWRTWidget((appArchList)[i]) ) { - // no recovery possible - doConsistency = EFalse; - break; + if ( KErrNone != iUsedUids.Append( (appArchList)[i] ) ) + { + // no recovery possible + doConsistency = EFalse; + break; + } } } } @@ -566,6 +605,23 @@ // on error use english iLprojName = _L("en"); } + + // Internalize the CWRT widgets, without consistency checking + // No multi-drive support for CWRT + TDriveUnit driveUnit(EDriveC); + CDir* installedListForDrive = NULL; + RArray installedListForDriveFlags; + TRAP_IGNORE( // consistency checking doesn't apply to CWRT + InternalizeXmlL( iRegistryCWRTXmlFileName, + driveUnit, + EFalse, + appArchList, + appArchListFlags, + installedListForDrive, + installedListForDriveFlags, + dirtyFlag ) ); + delete installedListForDrive; + installedListForDriveFlags.Close(); // List all drives in the system TDriveList driveList; @@ -675,13 +731,19 @@ delete installedListForDrive; installedListForDriveFlags.Close(); } // for + + // appArchList will not contain CWRT widgets, so + // consistency checking will not apply to them if ( doConsistency ) { AppArchListConsistency( appArchList, appArchListFlags ); - } + } + CleanupStack::PopAndDestroy( 2, &appArchList );//appArchListFlags, appArchList aDirtyFlag = dirtyFlag; + // Reset and Destroy entries in iOldEntries array + iOldEntries.ResetAndDestroy(); LOG1( "Internalize done, dirty flag %d", (TInt)dirtyFlag ); LOG_CLOSE; } @@ -712,15 +774,15 @@ readStream.Attach( file ); TInt error = KErrNone; - TInt entryCount = 0; + TInt entryCount = 0,errorCount =0; TRAP( error, entryCount = readStream.ReadInt32L() ); // TODO should limit entryCount to something like 1024 // for each entry in the registry file for ( TInt i = 0 ; i < entryCount; i++ ) { CWidgetEntry* entry = CWidgetEntry::NewL(); - CleanupStack::PushL( entry ); - + // push as delete entry so if we leave it will be handled + CleanupDeletePushL( entry ); // extract one entry TRAP( error, entry->InternalizeBinaryL( readStream ) ); @@ -742,13 +804,13 @@ TRAP( error, InsertL( entry ) ); if ( KErrNone != error ) { - CleanupStack::PopAndDestroy( entry ); + delete entry; } else { __ASSERT_DEBUG( res == entry, User::Invariant() ); // Entry was inserted successfully. - CleanupStack::Pop( entry ); + //CleanupStack::Pop( entry ); // add uid to AppArchList if not there, // this can happend due to UID // reallocation for UID collision resolution @@ -764,15 +826,25 @@ uidInt, uidInt ); } } + else + { + // Pop and delete the un-needed entry so it is not left behind. + errorCount++; + } } else { // entry error - CleanupStack::PopAndDestroy( entry ); + delete entry; } + CleanupStack::Pop(); //entry } // for CleanupStack::PopAndDestroy( 2, &file ); // readStream, file + if ( errorCount != 0 ) + { + User::Leave(KErrGeneral); + } } // ============================================================================ @@ -867,7 +939,16 @@ aDirtyFlag ); } if ( NULL != entry ) - { + { + CWidgetEntry* entry1 = NULL; + TInt uid = (*entry)[EUid]; + TInt pos = GetWidgetOldEntry( TUid::Uid( uid ), entry1 ); + if ( pos != -1 ) + { + entry->SetActive((iOldEntries[pos]->ActiveL())); + entry->SetFullView((iOldEntries[pos]->GetFullViewState())); + entry->SetMiniView((iOldEntries[pos]->GetMiniViewState())); + } TRAP( error, InsertL( entry ) ); if ( KErrNone != error ) { @@ -924,10 +1005,20 @@ // and value as an array of entry indices for that drive RPtrHashMap< TInt, CArrayFixFlat > driveEntryHashMap; CleanupClosePushL( driveEntryHashMap ); + CArrayFixFlat* cwrtWidgetArray = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL( cwrtWidgetArray ); for (TInt i = 0 ;i < iEntries.Count(); i++) { CWidgetEntry* entry = iEntries[i]; + + // Bypass if the widget is a CWRT widget, they're externalized + // independently + if (TUidAllocator::IsCWRTWidget(TUid::Uid((*entry)[EUid]))) { + cwrtWidgetArray->AppendL(i); + continue; + } + const TDesC& driveName = (*entry)[EDriveName]; TDriveUnit driveUnit( driveName ); CArrayFixFlat* array = @@ -1017,11 +1108,35 @@ } } } + + TDriveUnit driveUnit( EDriveC ); + iRegistryXmlTempFileName[0] = driveUnit.Name()[0]; + + iFs.CreatePrivatePath( driveUnit ); + + // a transactional file update to protect against + // disk full, etc: overwrite temp then rename temp to original + + TRAPD( error, + ExternalizeXmlL( iRegistryXmlTempFileName, cwrtWidgetArray ) ); + if ( KErrNone == error ) + { + // last steps in transactional update + BaflUtils::DeleteFile( iFs, iRegistryCWRTXmlFileName ); + BaflUtils::RenameFile( iFs, + iRegistryXmlTempFileName, + iRegistryCWRTXmlFileName ); + } + else // handle leave by deleting temp file + { + BaflUtils::DeleteFile( iFs, iRegistryXmlTempFileName ); + } for ( TInt i = 0; i < driveEntryHashMap.Count(); i++ ) { CleanupStack::Pop(); } + CleanupStack::PopAndDestroy( cwrtWidgetArray ); CleanupStack::Pop( &driveEntryHashMap ); driveEntryHashMap.ResetAndDestroy(); driveEntryHashMap.Close(); @@ -1775,7 +1890,8 @@ error = iAppArch.GetNextApp( info ); if ( KErrNone == error ) { - if ( TUidAllocator::IsWidget( info.iUid ) ) + if ( TUidAllocator::IsWidget( info.iUid ) && + !TUidAllocator::IsCWRTWidget( info.iUid ) ) { LOG2( " widget uid 0x%x (%d)", (TUint)(info.iUid.iUid), info.iUid.iUid ); @@ -1804,10 +1920,10 @@ { aUids.Reset(); } - else - { - error = KErrNone; - } + else + { + error = KErrNone; + } LOG_CODE( if ( aUids.Count() ) ) LOG1( "AppArchWidgetUids done widget count %d", aUids.Count() ); @@ -1968,7 +2084,7 @@ if ( !((aInstalledListForDriveFlags)[i] & EInstallListFlagEntry )) { TEntry dirEntry = (*aInstalledListForDrive)[i]; - if ( 0 == bundleIdentifier.Compare( dirEntry.iName ) ) + if ( 0 == bundleIdentifier.CompareF( dirEntry.iName ) ) { (aInstalledListForDriveFlags)[i] |= EInstallListFlagEntry; result = ETrue; @@ -2231,7 +2347,9 @@ void CWidgetRegistry::AppArchListConsistency( const RArray& aAppArchList, RArray& aAppArchListFlags ) { - LOG( "AppArchListConsistency" ); + LOG( "AppArchListConsistency" ); + RArray deRegisterList( KDefaultWidgetCount ); + CleanupClosePushL(deRegisterList); for ( TInt i = 0; i < aAppArchList.Count(); i++ ) { if ( !( aAppArchListFlags[i] & EAppListFlagEntry ) ) @@ -2239,29 +2357,16 @@ LOG_CODE( TInt uidIntLog = aAppArchList[i].iUid ); LOG2( " deregistered widget 0x%x (%d)", uidIntLog, uidIntLog ); - TRAP_IGNORE( iInstaller->DeregisterWidgetL( aAppArchList[i] ) ); + deRegisterList.Append(aAppArchList[i]); } } + if(deRegisterList.Count()) + { + TRAP_IGNORE( iInstaller->DeregisterWidgetsL( deRegisterList ) ); + } + CleanupStack::PopAndDestroy(&deRegisterList); LOG( "AppArchListConsistency done" ); } -void CWidgetRegistry::HandleAppListEvent(TInt aEvent) - { - TBool dirtyFlag = EFalse; - TInt parseError = KErrNone; - // Assume usual case and things are consistent - // and the registry entry file can be parsed and used. - TRAPD( error, InternalizeL( EFalse, - EFalse, - dirtyFlag, - parseError ) ); - if ( KErrNone == error ) - { - // internalize consistency enforcement may have altered registry - if ( dirtyFlag ) - { - TRAP_IGNORE( ExternalizeL(); ); - } - } - } + // End of File