phonebookui/Phonebook2/CommonUI/src/CPbk2StoreManager.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/CommonUI/src/CPbk2StoreManager.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,656 @@
+/*
+* Copyright (c) 2002-2007 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:  Phonebook 2 store manager.
+*
+*/
+
+
+// INCLUDE FILES
+#include <CPbk2StoreManager.h>
+
+// Phonebook 2
+#include "CPbk2CompressPolicyManager.h"
+#include <CPbk2StoreConfiguration.h>
+#include <RPbk2LocalizedResourceFile.h>
+#include <Pbk2DataCaging.hrh>
+#include <Pbk2CommonUi.rsg>
+
+// Virtual Phonebook
+#include <CVPbkContactManager.h>
+#include <MVPbkContactStoreList.h>
+#include <MVPbkContactStore.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <TVPbkContactStoreUriPtr.h>
+
+// System includes
+#include <barsread.h>
+#include <coemain.h>
+#include <aknnotewrappers.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+/**
+ * Checks is the error received from the database at the open
+ * fatal or not.
+ *
+ * @param aError    Error code.
+ * @return  ETrue if the error is a fatal one.
+ */
+TBool IsFatalDbOpenError( TInt aError )
+    {
+    TBool ret = ETrue;
+
+    switch ( aError )
+        {
+        case KErrNone:              // FALLTHROUGH
+        case KErrCancel:            // FALLTHROUGH
+        case KErrNoMemory:          // FALLTHROUGH
+        case KErrNotSupported:      // FALLTHROUGH
+        case KErrArgument:          // FALLTHROUGH
+        case KErrDied:              // FALLTHROUGH
+        case KErrInUse:             // FALLTHROUGH
+        case KErrServerTerminated:  // FALLTHROUGH
+        case KErrServerBusy:        // FALLTHROUGH
+        case KErrNotReady:          // FALLTHROUGH
+        case KErrAccessDenied:      // FALLTHROUGH
+        case KErrLocked:            // FALLTHROUGH
+        case KErrWrite:             // FALLTHROUGH
+        case KErrDisMounted:        // FALLTHROUGH
+        case KErrDiskFull:          // FALLTHROUGH
+        case KErrAbort:             // FALLTHROUGH
+        case KErrBadPower:          // FALLTHROUGH
+        case KErrDirFull:           // FALLTHROUGH
+        case KErrHardwareNotAvailable:
+            {
+            ret = EFalse;
+            break;
+            }
+
+        default:
+            {
+            // All error codes not handled above end up here,
+            // especially KErrCorrupt
+            break;
+            }
+        }
+
+    return ret;
+    }
+
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::CPbk2StoreManager
+// --------------------------------------------------------------------------
+//
+inline CPbk2StoreManager::CPbk2StoreManager
+        ( CVPbkContactManager& aContactManager,
+          CPbk2StoreConfiguration& aStoreConfiguration,
+          TBool aActOnConfigurationEvents ) :
+            iContactManager( aContactManager ),
+            iStoreConfiguration( aStoreConfiguration ),
+            iActOnConfigurationEvents( aActOnConfigurationEvents )
+    {
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::~CPbk2StoreManager
+// --------------------------------------------------------------------------
+//
+CPbk2StoreManager::~CPbk2StoreManager()
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::~CPbk2StoreManager(0x%x)"), this);
+
+    if ( iContactStores )
+        {
+        iContactStores->CloseAll(*this);
+        }
+
+    iFailedStores.Reset();
+    iFailedStores.Close();
+
+    iOpenedStores.Reset();
+    iOpenedStores.Close();
+
+    iStoreObservers.Reset();
+    iStoreObservers.Close();
+
+    delete iCompressPolicy;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2StoreManager::ConstructL()
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::ConstructL(0x%x)"), this);
+
+    iStoreConfiguration.AddObserverL( *this );
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::ConstructL(0x%x) Store configuration created"),
+        this);
+
+    iCompressPolicy =
+        CPbk2CompressPolicyManager::NewL( *this, iContactManager );
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::ConstructL(0x%x) end"), this);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::NewL
+// --------------------------------------------------------------------------
+//
+EXPORT_C CPbk2StoreManager* CPbk2StoreManager::NewL
+        ( CVPbkContactManager& aContactManager,
+          CPbk2StoreConfiguration& aStoreConfiguration,
+          TBool aActOnConfigurationEvents )
+    {
+    CPbk2StoreManager* self = new (ELeave) CPbk2StoreManager
+        ( aContactManager, aStoreConfiguration, aActOnConfigurationEvents );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::OpenStoresL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CPbk2StoreManager::OpenStoresL()
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::OpenStoresL"));
+
+    if (iContactStores)
+        {
+        iContactStores->CloseAll(*this);
+        }
+
+    iContactStores = &iContactManager.ContactStoresL();
+
+    if (iContactStores)
+        {
+        iContactStores->OpenAllL(*this);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::EnableCompression
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CPbk2StoreManager::EnableCompression(TBool aEnable)
+    {
+    if (aEnable)
+        {
+        iCompressPolicy->StartAllPolicies();
+        }
+    else
+        {
+        iCompressPolicy->StopAllPolicies();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::EnsureDefaultSavingStoreIncludedL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CPbk2StoreManager::EnsureDefaultSavingStoreIncludedL()
+    {
+    iStoreConfiguration.AddDefaultSavingStoreObserverL( *this );
+    iContactManager.LoadContactStoreL
+        ( iStoreConfiguration.DefaultSavingStoreL() );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::EnsureDefaultSavingStoreIncludedL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CPbk2StoreManager::EnsureCurrentConfigurationStoresIncludedL()
+    {
+    CVPbkContactStoreUriArray* uriArray =
+        iStoreConfiguration.CurrentConfigurationL();
+    CleanupStack::PushL( uriArray );
+    TInt count( uriArray->Count() );
+    for ( TInt i(0); i < count; ++i )
+        {
+        iContactManager.LoadContactStoreL( (*uriArray)[i] );
+        }
+    CleanupStack::PopAndDestroy( uriArray );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::RegisterStoreEventsL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::RegisterStoreEventsL
+        (const MVPbkContactStoreObserver& aObserver)
+    {
+    User::LeaveIfError( iStoreObservers.Append( &aObserver ) );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::DeregisterStoreEvents
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::DeregisterStoreEvents
+        (const MVPbkContactStoreObserver& aObserver)
+    {
+    const TInt index = iStoreObservers.Find( &aObserver );
+    if ( index > KErrNotFound )
+        {
+        iStoreObservers.Remove( index );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::CurrentlyValidStoresL
+// --------------------------------------------------------------------------
+//
+CVPbkContactStoreUriArray* CPbk2StoreManager::CurrentlyValidStoresL() const
+    {
+    CVPbkContactStoreUriArray* uris = CurrentlyValidShownStoresL();
+    CleanupStack::PushL( uris );
+
+    // If default saving store is not part of current config,
+    // check if it still valid store
+    TVPbkContactStoreUriPtr defaultSavingStoreUri =
+        iStoreConfiguration.DefaultSavingStoreL();
+    if ( !uris->IsIncluded( defaultSavingStoreUri ))
+        {
+        // Default store is not in the uris array
+        MVPbkContactStore* defaultStore =
+            iContactStores->Find( defaultSavingStoreUri );
+        // Add the default saving store to the list
+        // if it is loaded, opened and not failed
+        if ( defaultStore && IsStoreOpen(*defaultStore)
+            && iFailedStores.Find( defaultStore ) == KErrNotFound )
+            {
+            // Default saving store is valid store and successfully opened
+            uris->AppendL( defaultSavingStoreUri );
+            }
+        }
+    CleanupStack::Pop( uris );
+
+    return uris;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::CurrentlyValidShownStoresL
+// --------------------------------------------------------------------------
+//
+CVPbkContactStoreUriArray*
+        CPbk2StoreManager::CurrentlyValidShownStoresL() const
+    {
+    // Gets the list of URI's that compose the current configuration
+    CVPbkContactStoreUriArray* uris =
+        iStoreConfiguration.CurrentConfigurationL();
+
+    // Remove stores that are not open or are unavailable from the list
+    const TInt count = uris->Count();
+    for (TInt i = count - 1; i >= 0; --i)
+        {
+        TVPbkContactStoreUriPtr uri = (*uris)[i];
+        MVPbkContactStore* store = iContactStores->Find(uri);
+        if ( !(store && IsStoreOpen( *store ) &&
+             ( iFailedStores.Find( store ) == KErrNotFound ) ) )
+            {
+            // When the store is loaded, opened and not failed
+            // it is not removed from the URI list
+            uris->Remove(uri);
+            }
+        }
+
+    return uris;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::OpenComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::OpenComplete()
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::OpenComplete"));
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::StoreReady
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::StoreReady(
+        MVPbkContactStore& aContactStore)
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::StoreReady(0x%x)"),
+        &aContactStore);
+
+    // If the store was on the failed list, remove it
+    // from there
+    const TInt index = iFailedStores.Find(&aContactStore);
+    if (index != KErrNotFound)
+        {
+        iFailedStores.Remove(index);
+        }
+
+    // Add it to the open stores list
+    if (iOpenedStores.Find(&aContactStore) == KErrNotFound)
+        {
+        iOpenedStores.Append(&aContactStore);
+        }
+
+    // Notify observers
+    for (TInt i=0; i < iStoreObservers.Count(); ++i)
+        {
+        iStoreObservers[i]->StoreReady(aContactStore);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::StoreUnavailable
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::StoreUnavailable
+        ( MVPbkContactStore& aContactStore, TInt aReason )
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::StoreUnavailable(0x%x,%d)"),
+        &aContactStore, aReason);
+
+    // If the store is not found from the failed list,
+    // add it there and try to replace it.
+    // If the replace fails, the store will be found from the
+    // failed list, and the replace is not called again.
+
+    TBool informObservers = ETrue;
+    if ( iFailedStores.Find( &aContactStore ) == KErrNotFound )
+        {
+        iFailedStores.Append( &aContactStore );
+        if ( IsFatalDbOpenError( aReason ) )
+            {
+            informObservers = EFalse; // inform only if the replace fails too
+            TRAPD( err, ReplaceStoreL( aContactStore ) );
+            if ( err != KErrNone )
+                {
+                informObservers = ETrue;
+                CCoeEnv::Static()->HandleError( err );
+                }
+            }
+        }
+
+    // Remove the store from the open store list if it is there
+    const TInt index = iOpenedStores.Find( &aContactStore );
+    if ( index != KErrNotFound )
+        {
+        iOpenedStores.Remove( index );
+        }
+
+    // Notify observers
+    if ( informObservers )
+        {
+        for ( TInt i=0; i < iStoreObservers.Count(); ++i )
+            {
+            iStoreObservers[i]->StoreUnavailable( aContactStore, aReason );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::HandleStoreEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::HandleStoreEventL
+        ( MVPbkContactStore& aContactStore,
+          TVPbkContactStoreEvent aEvent )
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::HandleStoreEventL(0x%x,%d)"),
+        &aContactStore, aEvent.iEventType);
+
+    // Notify observers
+    for (TInt i=0; i < iStoreObservers.Count(); ++i)
+        {
+        iStoreObservers[i]->HandleStoreEventL(aContactStore, aEvent);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::ConfigurationChanged
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::ConfigurationChanged()
+    {
+    if ( iActOnConfigurationEvents )
+        {
+        TRAPD( err, HandleConfigurationChangedL() );
+        if ( err != KErrNone )
+            {
+            CCoeEnv::Static()->HandleError( err );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::ConfigurationChangedComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::ConfigurationChangedComplete()
+    {
+    if ( iActOnConfigurationEvents )
+        {
+        TRAPD( err,CloseUnnecessaryStoresL() );
+        if ( err != KErrNone )
+            {
+            CCoeEnv::Static()->HandleError( err );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::SavingStoreChanged
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::SavingStoreChanged()
+    {
+    TRAPD(err,HandleSavingStoreChangedL());
+    if (err != KErrNone)
+        {
+        CCoeEnv::Static()->HandleError(err);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::HandleConfigurationChangedL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::HandleConfigurationChangedL()
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2StoreManager::HandleConfigurationChangedL(0x%x)"),
+        this);
+
+    EnsureCurrentConfigurationLoadedAndOpenL();
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ( "CPbk2StoreManager::HandleConfigurationChangedL(0x%x) end" ),
+            this );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::EnsureCurrentConfigurationLoadedAndOpenL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::EnsureCurrentConfigurationLoadedAndOpenL()
+    {
+    CVPbkContactStoreUriArray* supportedConfiguration =
+            iStoreConfiguration.SupportedStoreConfigurationL();
+    CleanupStack::PushL(supportedConfiguration);
+
+    CVPbkContactStoreUriArray* currentConfiguration =
+            iStoreConfiguration.CurrentConfigurationL();
+    CleanupStack::PushL(currentConfiguration);
+
+    MVPbkContactStoreList& storeList = iContactManager.ContactStoresL();
+    const TInt supportedCount = supportedConfiguration->Count();
+    for (TInt i = 0; i < supportedCount; ++i )
+        {
+        // loop through the supported configurations and load and open
+        // all stores that are not part of the current configuration
+        TVPbkContactStoreUriPtr supportedStore = (*supportedConfiguration)[i];
+        if (currentConfiguration->IsIncluded(supportedStore))
+            {
+            // if the supported store is not loaded, then load it
+            if ( !storeList.Find(supportedStore) )
+                {
+                iContactManager.LoadContactStoreL(supportedStore);
+                }
+            // if the supported store is not open, then open it
+            MVPbkContactStore* store = storeList.Find(supportedStore);
+            if (store && iOpenedStores.Find(store) == KErrNotFound)
+                {
+                store->OpenL(*this);
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy( 2 ); // currentConfiguration,
+    }                                 // supportedConfiguration
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::CloseUnnecessaryStoresL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::CloseUnnecessaryStoresL()
+    {
+    CVPbkContactStoreUriArray* supportedConfiguration =
+        iStoreConfiguration.SupportedStoreConfigurationL();
+    CleanupStack::PushL( supportedConfiguration );
+
+    CVPbkContactStoreUriArray* currentConfiguration =
+        iStoreConfiguration.CurrentConfigurationL();
+    CleanupStack::PushL( currentConfiguration );
+
+    MVPbkContactStoreList& storeList = iContactManager.ContactStoresL();
+    TVPbkContactStoreUriPtr defaultStore =
+            iStoreConfiguration.DefaultSavingStoreL();
+    const TInt supportedCount = supportedConfiguration->Count();
+    for (TInt i = 0; i < supportedCount; ++i )
+        {
+        TVPbkContactStoreUriPtr supportedStore = (*supportedConfiguration)[i];
+        TBool isDefault(
+                    defaultStore.Compare(
+                                supportedStore,
+                                TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0 );
+
+        if ( !currentConfiguration->IsIncluded( supportedStore ) && !isDefault )
+            {
+            // close stores that are not part of the current configuration
+            // check whether the supported store is loaded
+            MVPbkContactStore* store = storeList.Find(supportedStore);
+            if (store)
+                {
+                // Close all which are not needed anymore
+                store->Close( *this );
+
+                // remove the store from the open store list if it is there
+                const TInt index = iOpenedStores.Find(store);
+                if (index != KErrNotFound)
+                    {
+                    iOpenedStores.Remove(index);
+                    }
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy( 2 ); // currentConfiguration,
+                                      // supportedConfiguration
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::HandleSavingStoreChangedL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::HandleSavingStoreChangedL()
+    {
+    CVPbkContactStoreUriArray* supportedConfiguration =
+            iStoreConfiguration.SupportedStoreConfigurationL();
+    CleanupStack::PushL(supportedConfiguration);
+
+    MVPbkContactStoreList& storeList = iContactManager.ContactStoresL();
+    const TInt supportedCount = supportedConfiguration->Count();
+    for ( TInt i = 0; i < supportedCount; ++i )
+        {
+        TVPbkContactStoreUriPtr supportedStore = (*supportedConfiguration)[i];
+        if ( supportedStore.Compare(
+                iStoreConfiguration.DefaultSavingStoreL(),
+                    TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0)
+            {
+            // load the plugin if it isnt loaded
+            if ( !storeList.Find(supportedStore))
+                {
+                iContactManager.LoadContactStoreL(supportedStore);
+                }
+            // if the saving store is not open, then open it
+            MVPbkContactStore* store = storeList.Find(supportedStore);
+            if (store && iOpenedStores.Find(store) == KErrNotFound)
+                {
+                store->OpenL(*this);
+                break; // the default has been loaded so break the loop
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // supportedConfiguration
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::IsStoreOpen
+// --------------------------------------------------------------------------
+//
+TBool CPbk2StoreManager::IsStoreOpen
+        ( MVPbkContactStore& aContactStore ) const
+    {
+    TBool ret = EFalse;
+    if ( iOpenedStores.Find( &aContactStore ) >= 0 )
+        {
+        ret = ETrue;
+        }
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2StoreManager::ReplaceStoreL
+// --------------------------------------------------------------------------
+//
+void CPbk2StoreManager::ReplaceStoreL
+        ( MVPbkContactStore& aContactStore )
+    {
+    // Display corrupted note
+    CAknNoteWrapper* note = new ( ELeave ) CAknNoteWrapper;
+    note->ExecuteLD( R_PBK2_NOTE_DATABASE_CORRUPTED );
+
+    // Replace database
+    aContactStore.ReplaceL( *this );
+    }
+
+// End of File