contentstorage/casrv/cawidgetscanner/src/cawidgetstoragehandler.cpp
branchRCL_3
changeset 113 0efa10d348c0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contentstorage/casrv/cawidgetscanner/src/cawidgetstoragehandler.cpp	Tue Aug 31 15:30:51 2010 +0300
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2008 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 FILES
+
+#include <badesca.h>
+#include <usif/scr/screntries.h>
+#include <hbtextresolversymbian.h>
+
+#include "widgetscannerutils.h"
+#include "cawidgetstoragehandler.h"
+#include "cadef.h"
+#include "cainnerentry.h"
+#include "cainnerquery.h"
+#include "castorageproxy.h"
+#include "caarraycleanup.inl"
+#include "calocalizationentry.h"
+#include "cawidgetscannerparser.h"
+#include "cawidgetscannerdef.h"
+
+using namespace Usif;
+
+// ============================ MEMBER FUNCTIONS ============================z===
+
+// -----------------------------------------------------------------------------
+// 
+// -----------------------------------------------------------------------------
+//
+CCaWidgetStorageHandler::CCaWidgetStorageHandler( CCaStorageProxy* aStorage,
+        Usif::RSoftwareComponentRegistry& aSoftwareRegistry, RFs& aFs ) :
+            iSoftwareRegistry(aSoftwareRegistry)
+    {
+    iStorage = aStorage;
+    iFs = aFs;
+    }
+
+// -----------------------------------------------------------------------------
+// 
+// -----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::ConstructL()
+    {
+    iParser = CCaWidgetScannerParser::NewL( iFs );
+    }
+
+// -----------------------------------------------------------------------------
+// 
+// -----------------------------------------------------------------------------
+//
+CCaWidgetStorageHandler* CCaWidgetStorageHandler::NewL(
+        CCaStorageProxy* aStorage,
+        Usif::RSoftwareComponentRegistry& aSoftwareRegistry, RFs& aFs )
+    {
+    CCaWidgetStorageHandler* self = NewLC( aStorage, aSoftwareRegistry, aFs );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// 
+// -----------------------------------------------------------------------------
+//
+CCaWidgetStorageHandler* CCaWidgetStorageHandler::NewLC(
+        CCaStorageProxy* aStorage,
+        Usif::RSoftwareComponentRegistry& aSoftwareRegistry, RFs& aFs )
+    {
+    CCaWidgetStorageHandler* self = new ( ELeave ) CCaWidgetStorageHandler(
+            aStorage, aSoftwareRegistry, aFs );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// 
+// -----------------------------------------------------------------------------
+//
+CCaWidgetStorageHandler::~CCaWidgetStorageHandler()
+    {
+    delete iParser;
+    iWidgetDBCache.ResetAndDestroy();
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::SynchronizeL()
+    {
+    FetchWidgetsL();
+    AddWidgetsL( iParser->WidgetsScanL( iWidgetDBCache ) );
+    RemoveWidgetsL();
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::AddL( const CCaWidgetDescription* aWidget )
+    {
+    CCaInnerEntry* entry = aWidget->GetEntryLC();
+    UpdateCompIdAndRemovableFlagL( aWidget->GetManifestFilePathName(), *entry );
+    iStorage->AddL( entry );
+
+    SetLocalizationsL( aWidget, entry->GetId() );
+
+    if ( entry->GetFlags() & ERemovable )
+        {
+        AddWidgetToDownloadCollectionL( entry );
+        }
+    CleanupStack::PopAndDestroy( entry );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::UpdateL( const CCaWidgetDescription* aWidget,
+        TUint aEntryId )
+    {
+    CCaInnerEntry* entry = aWidget->GetEntryLC();
+    UpdateCompIdAndRemovableFlagL( aWidget->GetManifestFilePathName(), *entry );
+    entry->SetId( aEntryId );
+    if ( !aWidget->IsMissing() && aWidget->IsUsed() )
+        {
+        entry->SetFlags( entry->GetFlags() & ~EUsed );
+        }
+    TItemAppearance itemAppearanceChange = EItemAppearanceNotChanged;
+    if ( ( entry->GetFlags() & EMissing ) || !( entry->GetFlags() & EVisible ) )
+        {
+        itemAppearanceChange = EItemAppeared;
+        }
+    entry->SetFlags( entry->GetFlags() & ~EMissing | EVisible );
+    iStorage->AddL( entry, EFalse, itemAppearanceChange );
+
+    SetLocalizationsL( aWidget, entry->GetId() );
+
+    if ( !aWidget->IsMissing() && ( entry->GetFlags() & ERemovable ) )
+        {
+        AddWidgetToDownloadCollectionL( entry );
+        }
+    CleanupStack::PopAndDestroy( entry );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::AddWidgetsL( const RWidgetArray& aWidgets )
+    {
+    const TInt newWidgetsCount = aWidgets.Count();
+    
+    for ( TInt i = 0; i < newWidgetsCount; ++i )
+        {
+        CCaWidgetDescription *const newWidget = aWidgets[i];
+        
+        newWidget->LocalizeTextsL();
+        
+        const TInt dbCacheIndex = 
+            iWidgetDBCache.Find( 
+                newWidget, CCaWidgetDescription::CompareUri );
+        
+        if ( dbCacheIndex != KErrNotFound )
+            {
+            CCaWidgetDescription *const cachedWidget = 
+                iWidgetDBCache[dbCacheIndex];
+            
+            cachedWidget->SetValid( ETrue );
+            
+            const TBool cachedDifferentThanNew = 
+                !cachedWidget->Compare( *newWidget );
+            
+            if ( cachedDifferentThanNew || cachedWidget->IsMissing() )
+                {
+                newWidget->SetFlag( EMissing, cachedWidget->IsMissing() );
+                newWidget->SetFlag( EUsed,  cachedWidget->IsUsed() );
+                newWidget->SetFlag( EVisible, cachedWidget->IsVisible() );
+                
+                UpdateL( newWidget, cachedWidget->GetEntryId() );
+                }
+            }
+        else
+            {
+            AddL( newWidget );
+            }
+        }
+    HbTextResolverSymbian::Init( _L(""), KLocalizationFilepathZ );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::RemoveWidgetsL()
+    {
+    const TInt cacheCount = iWidgetDBCache.Count();
+    for ( TInt i = 0; i < cacheCount; ++i)
+        {
+        CCaWidgetDescription *const cachedWidget = iWidgetDBCache[i];
+        if ( !cachedWidget->IsValid() )
+            {
+            if ( cachedWidget->GetMmcId() != KNullDesC )
+                {
+                RBuf currentMmcId;
+                currentMmcId.CreateL( KMassStorageIdLength );
+                currentMmcId.CleanupClosePushL();
+                WidgetScannerUtils::CurrentMmcId( iFs, currentMmcId );
+                if( cachedWidget->GetMmcId() == currentMmcId ||
+                        ( cachedWidget->GetMmcId() == KCaMassStorage() &&
+                        MassStorageNotInUse() ) )
+                    {
+                    //item was uninstalled so we remove its mmc id
+                    cachedWidget->RemoveMmcId();
+                    ClearVisibleFlagL( cachedWidget );
+                    }
+                else
+                    {
+                    SetMissingFlagL( cachedWidget );
+                    }
+                CleanupStack::PopAndDestroy( &currentMmcId );
+                }
+            else
+                {
+                //item was uninstalled so we remove its mmc id
+                ClearVisibleFlagL( cachedWidget );
+                }
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::AddWidgetToDownloadCollectionL(
+        const CCaInnerEntry* aEntry )
+    {
+    CCaInnerQuery* queryDownload = CCaInnerQuery::NewLC();
+    CDesC16ArrayFlat* downloadType = new ( ELeave ) CDesC16ArrayFlat(
+            KGranularityOne );
+    CleanupStack::PushL( downloadType );
+    downloadType->AppendL( KCaTypeCollectionDownload );
+    queryDownload->SetEntryTypeNames( downloadType );//query takes ownership
+    CleanupStack::Pop( downloadType );
+    queryDownload->SetRole( EGroupEntryRole );
+
+    RArray<TInt> idsGroup;
+    CleanupClosePushL( idsGroup );
+    iStorage->GetEntriesIdsL( queryDownload, idsGroup );
+
+    TCaOperationParams operParams;
+    operParams.iOperationType = TCaOperationParams::EPrepend;
+    operParams.iGroupId = idsGroup[0];
+    operParams.iBeforeEntryId = 0;
+    CleanupStack::PopAndDestroy( &idsGroup );
+
+    RArray<TInt> idsEntry;
+    CleanupClosePushL( idsEntry );
+    idsEntry.Append( aEntry->GetId() );
+    iStorage->OrganizeL( idsEntry, operParams );
+
+    CleanupStack::PopAndDestroy( &idsEntry );
+    CleanupStack::PopAndDestroy( queryDownload );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::FetchWidgetsL()
+    {
+    CCaInnerQuery* query = CCaInnerQuery::NewLC();
+    CDesC16ArrayFlat* widgetType = new ( ELeave ) CDesC16ArrayFlat(
+            KGranularityOne );
+    CleanupStack::PushL( widgetType );
+    widgetType->AppendL( KCaTypeWidget );
+    query->SetEntryTypeNames( widgetType );//transfers ownership to query
+    CleanupStack::Pop( widgetType );
+
+    RPointerArray<CCaInnerEntry> entries;
+    CleanupResetAndDestroyPushL( entries );
+    iStorage->GetEntriesL( query, entries );
+
+    iWidgetDBCache.ResetAndDestroy();
+    for ( TInt i = 0; i < entries.Count(); i++ )
+        {
+        CCaWidgetDescription* widget = CCaWidgetDescription::NewLC( entries[i] );
+        iWidgetDBCache.AppendL( widget ); //iWidgets takes ownership
+        CleanupStack::Pop( widget );
+        }
+    CleanupStack::PopAndDestroy( &entries );
+    CleanupStack::PopAndDestroy( query );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::SetMissingFlagL(
+        const CCaWidgetDescription* aWidget )
+    {
+    if ( !aWidget->IsMissing() )
+        {
+        CCaInnerEntry* entry = aWidget->GetEntryLC();
+        entry->SetFlags( ( entry->GetFlags() | EMissing ) & ~EUninstall );
+        if ( aWidget->IsUsed() )
+            {
+            entry->SetFlags( entry->GetFlags() | EUsed );
+            }
+        iStorage->AddL( entry, EFalse, EItemDisappeared );
+        CleanupStack::PopAndDestroy( entry );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCaWidgetStorageHandler::ClearVisibleFlagL(
+        const CCaWidgetDescription* aWidget )
+    {
+    if ( aWidget->IsVisible() )
+        {
+        CCaInnerEntry* entry = aWidget->GetEntryLC();
+        entry->SetFlags( entry->GetFlags()
+                & ~EUninstall
+                & ~EVisible 
+                & ~EMissing 
+                & ~EUsed );
+        iStorage->AddL( entry, EFalse, EItemDisappeared );
+        CleanupStack::PopAndDestroy( entry );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+TBool CCaWidgetStorageHandler::MassStorageNotInUse()
+    {
+    TBool massStorageNotInUse( ETrue );
+    TInt drive;
+    if( DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, drive ) ==
+        KErrNone )
+        {
+        TUint status;
+        if( DriveInfo::GetDriveStatus( iFs, drive, status ) == KErrNone &&
+            ( status & DriveInfo::EDriveInUse ) )
+            {
+            massStorageNotInUse = EFalse;
+            }
+        }
+    return massStorageNotInUse;
+    }
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+
+void CCaWidgetStorageHandler::SetLocalizationsL(
+        const CCaWidgetDescription* aWidget, TInt aEntryId )
+    {
+    RBuf filename;
+    filename.CreateL( aWidget->GetTranslationFileName().Length() + 1 ); //1 for _
+    CleanupClosePushL( filename );
+    filename.Copy( aWidget->GetTranslationFileName() );
+    filename.Append( KWidgetScannerUnderline );
+
+    // prepare localizations
+    if ( aWidget->GetTitle().Length() > 0 && aWidget->GetTitle().Compare(
+            aWidget->GetStringIdTitle() ) )
+    // lets do not add localization when key and value are identical
+        {
+        CCaLocalizationEntry* titleEntry = CCaLocalizationEntry::NewL();
+        CleanupStack::PushL( titleEntry );
+        titleEntry->SetTableNameL( KLocalizationCaEntry );
+        titleEntry->SetAttributeNameL( KLocalizationEnText );
+        titleEntry->SetStringIdL( aWidget->GetStringIdTitle() );
+        titleEntry->SetQmFilenameL( filename );
+        titleEntry->SetRowId( aEntryId );
+        iStorage->AddLocalizationL( *titleEntry );
+        CleanupStack::PopAndDestroy( titleEntry );
+        }
+    if ( aWidget->GetDescription().Length() > 0 &&
+            aWidget->GetDescription().Compare(
+                    aWidget->GetStringIdDescription() ) )
+    // lets do not add localization when key and value are identical
+        {
+        CCaLocalizationEntry* descEntry = CCaLocalizationEntry::NewL();
+        CleanupStack::PushL( descEntry );
+        descEntry->SetTableNameL( KLocalizationCaEntry );
+        descEntry->SetAttributeNameL( KLocalizationEnDescription );
+        descEntry->SetStringIdL( aWidget->GetStringIdDescription() );
+        descEntry->SetQmFilenameL( filename );
+        descEntry->SetRowId( aEntryId );
+        iStorage->AddLocalizationL( *descEntry );
+        CleanupStack::PopAndDestroy( descEntry );
+        }
+    CleanupStack::PopAndDestroy( &filename );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+
+void CCaWidgetStorageHandler::UpdateCompIdAndRemovableFlagL(
+        const TDesC& aManifestFilePathName, CCaInnerEntry& aEntry ) const
+    {
+    RArray<TComponentId> componentIds;
+    CleanupClosePushL( componentIds );
+
+    CComponentFilter* const fileNameFilter = CComponentFilter::NewLC();
+    fileNameFilter->SetFileL( aManifestFilePathName );
+    iSoftwareRegistry.GetComponentIdsL( componentIds, fileNameFilter );
+
+    CleanupStack::PopAndDestroy( fileNameFilter );
+
+    if( componentIds.Count() == 1 )
+        {
+        RBuf newComponentId;
+        newComponentId.CleanupClosePushL();
+        newComponentId.CreateL( sizeof(TComponentId) + 1 );
+        newComponentId.AppendNum( componentIds[0] );
+
+        RBuf oldComponentId;
+        oldComponentId.CleanupClosePushL();
+        oldComponentId.CreateL( KCaMaxAttrValueLen );
+
+        const TBool componentIdAttributeFound = aEntry.FindAttribute(
+                KCaComponentId, oldComponentId );
+
+        if( !componentIdAttributeFound || oldComponentId.Compare(
+                newComponentId ) != 0 )
+            {
+            // 'add' or 'update' the component id attribute value
+            aEntry.AddAttributeL( KCaComponentId, newComponentId );
+            }
+        CComponentEntry* entry = CComponentEntry::NewLC();
+        iSoftwareRegistry.GetComponentL( componentIds[0] , *entry );
+        if( entry->IsRemovable() )
+            {
+            aEntry.SetFlags( aEntry.GetFlags() | ERemovable );
+            }
+        CleanupStack::PopAndDestroy( entry );
+        CleanupStack::PopAndDestroy( &oldComponentId );
+        CleanupStack::PopAndDestroy( &newComponentId );
+        }
+
+    CleanupStack::PopAndDestroy( &componentIds );
+    }
+
+//  End of File