mmserv/radioutility/presetutility/src/cenrephandler.cpp
changeset 14 80975da52420
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/radioutility/presetutility/src/cenrephandler.cpp	Mon May 03 12:59:52 2010 +0300
@@ -0,0 +1,390 @@
+/*
+* Copyright (c) 2009 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:
+*
+*
+*/
+
+
+// System includes
+#include <centralrepository.h>
+#include <s32mem.h>
+
+// User includes
+#include "cenrephandler.h"
+#include "presetcrkeys.h"
+#include <preset.h>
+#include "cenrepbookkeeping.h"
+#include "trace.h"
+
+
+class TChannelIndexList
+    {
+public:
+    TInt iChannelIndex;
+    TInt iNameIndex;
+    TInt iFrequencyIndex;
+    TInt iUrlIndex;
+    TInt iRestOfParametersIndex;
+    };
+
+// ============= STATIC FUNCTIONS ==============
+
+static TInt CalculateChannelIndexes( const TInt aChannelIndex,  TChannelIndexList& aChannelIndexList)
+    {
+    FUNC_LOG;
+    TInt err( KErrNone );
+    if ( ( KMaxNumberOfPresetStations <= aChannelIndex ) ||
+            ( 0 >  aChannelIndex ) )
+        {
+        err = KErrArgument;
+        }
+    else
+        {
+        aChannelIndexList.iChannelIndex = 
+         KRadioPresetChannel1 + ( KNbrOfParametersPerChannelSequence * aChannelIndex );
+        aChannelIndexList.iNameIndex =
+            aChannelIndexList.iChannelIndex + KChannelNameOffset;        
+        aChannelIndexList.iFrequencyIndex =
+            aChannelIndexList.iChannelIndex + KFrequencyOffset;        
+        aChannelIndexList.iUrlIndex =
+            aChannelIndexList.iChannelIndex + KUrlOffset;        
+        aChannelIndexList.iRestOfParametersIndex =
+            aChannelIndexList.iChannelIndex + KRestOfParametersOffset;
+        }
+    return err;
+    }
+
+// ============= MEMBER FUNCTIONS ==============
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CCenrepHandler::CCenrepHandler()
+    {
+    FUNC_LOG;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ConstructL()
+    {
+    FUNC_LOG;
+    iCentralRepository = CRepository::NewL( KCRUidPresetUtility );
+    iBookKeeping = new (ELeave) CCenrepBookKeeping;
+    ReadBookKeepingL();
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CCenrepHandler* CCenrepHandler::NewL()
+    {
+    FUNC_LOG;
+    CCenrepHandler* self = new (ELeave) CCenrepHandler();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CCenrepHandler::~CCenrepHandler()
+    {
+    FUNC_LOG;
+    delete iCentralRepository;
+    delete iBookKeeping;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::MaxPresetCount() const
+    {
+    FUNC_LOG;
+    return KMaxNumberOfPresetStations;
+    }
+
+// -----------------------------------------------------------------------------
+// Get the current number of presets
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::PresetCount() const
+    {
+    FUNC_LOG;
+    return iBookKeeping->PresetCount();
+    }
+
+// -----------------------------------------------------------------------------
+// Gets the first preset
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::FirstPreset() const
+    {
+    FUNC_LOG;
+    return iBookKeeping->FirstIndex();
+    }
+
+// -----------------------------------------------------------------------------
+// Get the next preset index that has been set, given the current index
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::NextPreset( TInt aFromIndex ) const
+    {
+    FUNC_LOG;
+    return iBookKeeping->NextIndex( aFromIndex );
+    }
+
+// -----------------------------------------------------------------------------
+// Delete the current preset
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::DeletePreset( TInt aIndex )
+    {
+    FUNC_LOG;
+    TInt err( KErrNone );
+    if ( -1 == aIndex )
+        {
+        // Delete all
+        TChannelIndexList channelIndexList;
+        for (  TInt j( FirstPreset() ); 0 <= j;  j = FirstPreset() )
+            {
+            INFO_1("Deleting index: %i", j );
+            if ( KErrNone == CalculateChannelIndexes( j, channelIndexList ) )
+                {                
+                iCentralRepository->Delete( channelIndexList.iNameIndex );    
+                iCentralRepository->Delete( channelIndexList.iFrequencyIndex );   
+                iCentralRepository->Delete( channelIndexList.iUrlIndex );
+                iCentralRepository->Delete( channelIndexList.iRestOfParametersIndex );
+                iBookKeeping->RemoveIndex( j );        
+                }
+            }
+        }
+    else
+        {
+        TChannelIndexList channelIndexList;
+        err = CalculateChannelIndexes( aIndex, channelIndexList );
+        if ( KErrNone == err )
+            {
+            iCentralRepository->Delete( channelIndexList.iNameIndex );    
+            iCentralRepository->Delete( channelIndexList.iFrequencyIndex );   
+            iCentralRepository->Delete( channelIndexList.iUrlIndex );
+            iCentralRepository->Delete( channelIndexList.iRestOfParametersIndex );
+            iBookKeeping->RemoveIndex( aIndex );        
+            }
+        }
+    if ( KErrNone == err )
+        {
+        SaveBookKeeping();
+        }
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CCenrepHandler::SavePresetL( const TPreset& aPreset, TInt aIndex )
+    {
+    FUNC_LOG;
+    if ( 0 > aIndex )
+        {
+        aIndex = iBookKeeping->FindUnusedIndex();
+        }
+    if ( 0 > aIndex )
+        {
+        User::Leave( KErrDiskFull ); // Not really a good code for this
+        }
+    TChannelIndexList channelIndexList;
+    User::LeaveIfError( CalculateChannelIndexes( aIndex, channelIndexList) );
+
+    // First save name to its own key in the key sequence.
+    User::LeaveIfError( iCentralRepository->Set( channelIndexList.iNameIndex, aPreset.Name() ) );
+
+    // Frequency  to its own key in the key sequence.
+    User::LeaveIfError( iCentralRepository->Set( channelIndexList.iFrequencyIndex, (TInt)aPreset.Frequency() ) );
+
+    // Url to its own key in the key sequence.
+    User::LeaveIfError( iCentralRepository->Set( channelIndexList.iUrlIndex, aPreset.Url() ) );
+
+    // Then externalize the rest of the data to a common key.
+    TInt err( KErrNone );
+    TInt length( aPreset.MyExternalizedDataSize() );
+    TUint i ( 1 );
+    INFO_1( "aPreset.MyExternalizedDataSize()=%i", length );
+    for ( TBool cont = ( 0 < length ) ? ETrue : EFalse; (cont); cont = ( KErrOverflow == err ) ?  ETrue : EFalse ) 
+        {
+        HBufC8* buf = HBufC8::NewLC( i * length  );
+        TPtr8 bufPtr = buf->Des();
+        RDesWriteStream outStream( bufPtr );
+        CleanupClosePushL( outStream );
+        TRAP( err, aPreset.ExternalizeL( outStream ) );
+        if ( KErrNone == err )
+            {
+            outStream.CommitL();
+            User::LeaveIfError( iCentralRepository->Set( channelIndexList.iRestOfParametersIndex, *buf ) );
+            }
+        else
+            {
+            INFO_2( "SavePresetL bigger buffer (%i) needed than required by aPreset.MyExternalizedDataSize()=%i", i*length, aPreset.MyExternalizedDataSize() );
+            ++i;
+            }
+        CleanupStack::PopAndDestroy( &outStream );
+        CleanupStack::PopAndDestroy( buf );
+        }
+    User::LeaveIfError( err );
+
+    iBookKeeping->AddIndex( aIndex );
+    SaveBookKeeping();
+    return aIndex;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ReadPresetL( TInt aIndex, TPreset& aPreset )
+    {
+    FUNC_LOG;
+
+    // Read name from its own key in the key sequence
+    TChannelIndexList channelIndexList;
+    User::LeaveIfError( CalculateChannelIndexes( aIndex, channelIndexList) );
+    TPresetName tempChannelName;
+    User::LeaveIfError( iCentralRepository->Get(channelIndexList.iNameIndex, tempChannelName ) );
+    aPreset.SetName( tempChannelName );
+
+    // Read frequency from its own key in the key sequence
+    TInt frequency( 0 );
+    User::LeaveIfError( iCentralRepository->Get( channelIndexList.iFrequencyIndex, frequency ) );
+    aPreset.SetFrequency( frequency );
+
+    // Read url from its own key in the key sequence
+    TRadioUrl tempUrlName;
+    TInt err = iCentralRepository->Get( channelIndexList.iUrlIndex, tempUrlName );
+    if ( KErrNone == err )
+        {        
+        aPreset.SetUrl( tempUrlName );
+        }
+    else if ( KErrNotFound == err )
+        {
+        // This is an optional parameter.
+        }
+    else
+        {
+        User::Leave( err );
+        }
+                      
+
+    // Then use the below code to internalize rest of parameters from the common key
+    TInt actualLength( aPreset.MyExternalizedDataSize() );
+    INFO_1( "ReadPresetL aPreset.MyExternalizedDataSize()=%i", actualLength );
+    for ( TBool cont = ( 0 < actualLength ) ? ETrue : EFalse; (cont); cont = ( KErrOverflow == err ) ?  ETrue : EFalse ) 
+        {
+        HBufC8* buf = HBufC8::NewLC( actualLength );
+        TPtr8 bufPtr = buf->Des();
+        err = iCentralRepository->Get( channelIndexList.iRestOfParametersIndex, bufPtr, actualLength );
+        if ( ( KErrNone == err ) && ( 0 < buf->Length() ) )
+            {
+            RDesReadStream inStream;
+            inStream.Open( *buf );
+            CleanupClosePushL( inStream );       
+            aPreset.InternalizeL( inStream );        
+            CleanupStack::PopAndDestroy( &inStream );
+            }
+        else if ( KErrNotFound == err )
+            {
+            // This is not filled by CT tool even though name, frequency and URL might be 
+            // filled for the current channel. Don't leave.
+            INFO_1( "ReadPresetL KErrNotFound, key=%i", channelIndexList.iRestOfParametersIndex );
+            }
+        else if ( KErrOverflow == err )
+            {
+            INFO_2( "ReadPresetL KErrOverflow, buf->Length()=%i actualLength=%i", buf->Length(), actualLength );
+            // Trying again with actual with buffer that can store the whole key
+            }
+        else
+            {
+            User::Leave( err );
+            }
+        CleanupStack::PopAndDestroy(buf);
+        } // for (;;) 
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ReadBookKeepingL()
+    {
+    FUNC_LOG;
+    TPtr8 bufPtr = iBookKeeping->BookKeepingData();
+
+    TInt err( iCentralRepository->Get( KRadioBookKeepingLocation, bufPtr ) );
+    if ( KErrNotFound == err )
+        {
+        // Bookkeeping does not exist. Search possible preconfigured channels.
+        ReadPreDefinedPresetsL();
+        err = KErrNone;
+        }
+    User::LeaveIfError( err );
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::SaveBookKeeping()
+    {
+    FUNC_LOG;
+    TInt err( iCentralRepository->Set( KRadioBookKeepingLocation, iBookKeeping->BookKeepingData() ) );
+    if ( KErrNone !=  err )
+        {
+        INFO_1("Saving of BookKeeping failed with error: %i ", err)
+        // It is better to destroy data that is out of sync
+        iCentralRepository->Delete( KRadioBookKeepingLocation );
+        // Go on with local bookkeeping data
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CCenrepHandler::ReadPreDefinedPresetsL()
+    {
+    FUNC_LOG;
+    TInt frequency ( 0 );
+    TInt err( KErrNone );
+    TChannelIndexList channelIndexList;
+    iBookKeeping->Clear();
+    for(TInt index = 0; index < KMaxNumberOfPresetStations; index++)
+        {
+        User::LeaveIfError( CalculateChannelIndexes( index, channelIndexList) );
+        err = iCentralRepository->Get( channelIndexList.iFrequencyIndex, frequency );
+        if ( KErrNone ==  err )
+            {
+            iBookKeeping->AddIndex( index );
+            }
+        } 
+    SaveBookKeeping();
+    }