cbs/CbsServer/ServerSrc/CCbsDbImpSettings.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Mar 2010 09:40:14 +0200
changeset 12 ae8abd0db65c
parent 0 ff3b6d0fd310
permissions -rw-r--r--
Revision: 201007 Kit: 201011

/*
* Copyright (c) 2003 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:  This module contains the implementation of CCbsDbImpSettings class 
*                member functions.
*    
*                This class represents CBS settings stored in the database.
*                A functionality is provided here to access, modify, store and restore
*                settings.
*
*/


//  INCLUDE FILES
#include <centralrepository.h>
#include "CbsServerPrivateCRKeys.h"
#include "MCbsDbSettingsObserver.H"
#include "CbsServerPanic.h"
#include "CCbsDbImpSettings.H"
#include "CbsDbConstants.h"
#include "CbsStreamHelper.h"
#include "CbsUtils.h"
#include "CbsLogger.h"

// CONSTANTS
// Used if languages cannot be read from Shared Data.
const TInt8 KDefaultsLanguageSubscribedValue = '1';


// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::CCbsDbImpSettings
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CCbsDbImpSettings::CCbsDbImpSettings(  
    CCbsDbImp& aDatabase )
    : iDatabase( aDatabase )
    {
    }

// -----------------------------------------------------------------------------
// CCbsDbImp::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CCbsDbImpSettings::ConstructL()
    {
    // Create an array for settings event observers.
    iObservers = new ( ELeave ) CArrayFixFlat< MCbsDbSettingsObserver* >( 
        KCbsDbObserverArraySize );

    TRAPD( result, LoadSettingsL() );
	if ( result != KErrNone )   
		{
		User::Leave( result );
		}
		
    __TEST_INVARIANT;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CCbsDbImpSettings* CCbsDbImpSettings::NewL( CCbsDbImp& aDatabase )
    {
    CCbsDbImpSettings* self = 
        new ( ELeave ) CCbsDbImpSettings( aDatabase );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop();
    return self;
    }
    
// Destructor
CCbsDbImpSettings::~CCbsDbImpSettings()
    {
    CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpSettings::~CCbsDbImpSettings()");
    delete iObservers;
    CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpSettings::~CCbsDbImpSettings()");
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::SetTopicDetectionStatusL
// Changes the topic detection status.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCbsDbImpSettings::SetTopicDetectionStatusL( 
    TBool aStatus )
    {

    // If the value does not change we do nothing but return
    if ( aStatus != iSettings.iTopicDetectionStatus ) 
        {
        // First we change the status value in cache.
        iSettings.iTopicDetectionStatus = aStatus;

        // Now we try to save the modified settings to the store
        if ( !SaveSettings() ) 
            {        
            // If an error occured, we leave the status unchanged.
            if ( iSettings.iTopicDetectionStatus ) 
                {
                iSettings.iTopicDetectionStatus = EFalse;
                }
            else 
                {
                iSettings.iTopicDetectionStatus = ETrue;
                }

            // and then leave again
            User::Leave( KErrWrite );
            }

        // Inform observers about the changed status
        TInt amountOfObservers( iObservers->Count() );
        for ( TInt i( 0 ); i < amountOfObservers; i++ )
            {
            iObservers->At( i )->TopicDetectionStatusChangedIndL();
            }                
        }    
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::SaveSettings
// Saves the settings to CenRep
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CCbsDbImpSettings::SaveSettings()
    {
    __TEST_INVARIANT;
    TBool result( ETrue );

    // Try to save the settings.
    TRAPD( error, DoSaveSettingsL() );
    if ( error != KErrNone )
        {
        // Some kind of failure occurred.
        __TEST_INVARIANT;        
        result = EFalse;
        }

    __TEST_INVARIANT;
    return result;
    }    

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::DoSaveSettingsL
// Saves the settings to CenRep
// The method leaves in case the writing to the does not succeed.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCbsDbImpSettings::DoSaveSettingsL()
    {
    
    TInt reception( iSettings.iReceptionStatus );
    TInt topicDetection( iSettings.iTopicDetectionStatus );
    
    TBuf< ECbsCount > languages; 
   
    for ( TInt i( 0 ); i < ECbsCount; i++ )
        {
        languages.AppendNum( iSettings.iLanguageStatus.iLanguages[i] );	
        }
   
    // Connecting and initialization
    CRepository* repository = CRepository::NewL( KCRUidCellBroadcast );
 
    // Get the values from Central Repository
    repository->Set( KCbsReception, reception );
    repository->Set( KCbsTopicDetection, topicDetection );
    repository->Set( KCbsLanguages, languages );
    
    // Closing the connection
    delete repository;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::GetTopicDetectionStatus
// Returns the current value of the topic detection status.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCbsDbImpSettings::GetTopicDetectionStatus( 
    TBool& aStatus ) const
    {
    // We just give the asked status value from cache to aStatus
    aStatus = iSettings.iTopicDetectionStatus;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::SetReceptionStatusL
// Changes the reception status.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCbsDbImpSettings::SetReceptionStatusL( 
    TBool aStatus )    
    {

    // If the value does not change we do nothing but return
    if ( aStatus != iSettings.iReceptionStatus ) 
        {
        // First we change the status value in iSettings
        iSettings.iReceptionStatus = aStatus;

        // Now we try to save the modified settings to the store
        if ( !SaveSettings() ) 
            {
            // If an error occured, we leave the status unchanged.
            if ( iSettings.iReceptionStatus ) 
                {
                iSettings.iReceptionStatus = EFalse;
                }
            else 
                {
                iSettings.iReceptionStatus = ETrue;
                }

            // and then leave.
            User::Leave( KErrWrite );
            }

        // Inform observers about the changed status
        TInt amountOfObservers( iObservers->Count() );
        for ( TInt i( 0 ); i < amountOfObservers; i++ )
            {
            iObservers->At( i )->ReceptionStatusChangedIndL();
            }                
        }    
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::GetReceptionStatus
// Returns the current value of the topic reception status.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCbsDbImpSettings::GetReceptionStatus( 
    TBool& aStatus ) const
    {
    // We just give the asked status value from cache to aStatus
    aStatus = iSettings.iReceptionStatus;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::SetLanguagesL
// Changes the preferred languages.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::SetLanguagesL( 
    const TCbsDbLanguages& aLanguages )
    {
    __TEST_INVARIANT;

    // Compare language settings.
    if ( !IsLanguagesEqual( aLanguages, iSettings.iLanguageStatus ) ) 
        {
        // We take a backup of the language status before changing the value.
        TCbsDbLanguages oldLanguageStatus = iSettings.iLanguageStatus;
        
        // We change the language status value
        iSettings.iLanguageStatus = aLanguages;

        // Now we try to save the modified settings struct to the store
        if ( !SaveSettings() ) 
            {
            // If an error occured, we leave the settings unchanged.
            iSettings.iLanguageStatus = oldLanguageStatus;
            User::Leave( KErrWrite );
            }

        // Inform observers about the changed status
        TInt amountOfObservers( iObservers->Count() );
        for ( TInt i( 0 ); i < amountOfObservers; i++ )
            {
            iObservers->At( i )->LanguagesChangedIndL();
            }    
        }
    
    __TEST_INVARIANT;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::GetLanguages
// Returns the preferred languages.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::GetLanguages( 
    TCbsDbLanguages& aLanguages ) const
    {
    // We just give the asked status value from cache to aLanguages
    aLanguages = iSettings.iLanguageStatus;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::AddObserverL
// Adds an observer to the settings.
// Observers are notified when an event occurs on the settings.    
// Panics on debug mode if aObserver is null.  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::AddObserverL( 
    MCbsDbSettingsObserver* aObserver )
    {
    __TEST_INVARIANT;
    __ASSERT_DEBUG( aObserver!=0, CbsServerPanic( ECbsObserverNull ) );
    iObservers->AppendL( aObserver );
    __TEST_INVARIANT;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::RemoveObserver
// Removes database observer.
// The method will panic, if there is no such observer added
// or the given observer is null.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::RemoveObserver( 
    const MCbsDbSettingsObserver* aObserver )
    {
    __ASSERT_DEBUG( aObserver != 0, CbsServerPanic( ECbsObserverNull ) );

    // Find the observer to remove
    TInt amountOfObservers( iObservers->Count() );
    TBool found( EFalse );

    for ( TInt index( 0 ); ( index < amountOfObservers ) && !found; index++ )
        {
        if ( aObserver == iObservers->At( index ) )
            {
            iObservers->Delete( index );
            iObservers->Compress();  
            found = ETrue;            
            }
        }

    // Panic if the observer was not found
    if ( !found )
        {
        CbsServerPanic( ECbsObserverNotFound );
        }    
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::LoadSettingsL
// Loads the settings, i.e. values for reception status, topic detection
// and language subscriptions.
// These values are retrieved from Central Repository, associated with
// the UID of CbsServer.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::LoadSettingsL()
    {
    CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpSettings::LoadSettingsL()");
    
    // Connecting and initialization
    CRepository* repository = CRepository::NewL( KCRUidCellBroadcast );
    
    TBuf< ECbsCount > languages;
    languages.Zero();

    TInt reception( 0 );
    TInt topicDetection( 0 );
    
    // Get the values from Central Repository
    repository->Get( KCbsReception, reception );
    repository->Get( KCbsTopicDetection, topicDetection );
    repository->Get( KCbsLanguages, languages );
    
    // Closing the connection
    delete repository;
    
    CBSLOGSTRING("CBSSERVER: CCbsDbImpSettings::LoadSettingsL(): Repository reading finished.");

    iSettings.iReceptionStatus = reception == 0 ? EFalse : ETrue;
    iSettings.iTopicDetectionStatus = topicDetection == 0 ? EFalse : ETrue;

    if ( languages.Length() != ECbsCount )
        {
        User::Leave( KErrCorrupt );
        }
    
    for ( TInt i( 0 ); i < ECbsCount; i++ )
        {
        iSettings.iLanguageStatus.iLanguages[ i ] = 
            ( languages[ i ] == KDefaultsLanguageSubscribedValue );
        }
    CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpSettings::LoadSettingsL()");
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::IsLanguagesEqual
// Determines whether the language settings are equal. 
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
TBool CCbsDbImpSettings::IsLanguagesEqual( 
    const TCbsDbLanguages& aLanguage1, 
    const TCbsDbLanguages& aLanguage2 ) const
    {
    // Go through each language settings.
    for ( TInt index( 0 ); index < ECbsCount; index++ )
        {
        if ( aLanguage1.iLanguages[ index ] != aLanguage2.iLanguages[ index ] )
            {
            return EFalse;
            }
        }

    // Equal.
    return ETrue;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::SetDefaultLanguageSettings
// Sets default language settings.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::SetDefaultLanguageSettings( 
    TCbsDbLanguages& aLanguage ) const
    {
    // First, set all languages to false.
    for ( TInt index( 0 ); index < ECbsAll; index++ )
        {
        aLanguage.iLanguages[ index ] = EFalse;
        }

    // And then set the "All"-choice to true.
    aLanguage.iLanguages[ ECbsAll ] = ETrue;
    }

// -----------------------------------------------------------------------------
// CCbsDbImpSettings::__DbgTestInvariant
// Checks that the object is in a valid state, and panics if it is not.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
void CCbsDbImpSettings::__DbgTestInvariant() const
    {
#if defined(_DEBUG)
    if ( iSettings.iReceptionStatus < 0 || iSettings.iReceptionStatus > 1 ||
        iSettings.iTopicDetectionStatus < 0 || 
        iSettings.iTopicDetectionStatus > 1 ||
        iObservers == NULL )
        {
        User::Invariant();
        }
#endif
    }

// ========================== OTHER EXPORTED FUNCTIONS =========================
//  End of File