/*
* 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