mmserv/radioutility/presetutility/src/cenrephandler.cpp
changeset 14 80975da52420
equal deleted inserted replaced
12:5a06f39ad45b 14:80975da52420
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // System includes
       
    21 #include <centralrepository.h>
       
    22 #include <s32mem.h>
       
    23 
       
    24 // User includes
       
    25 #include "cenrephandler.h"
       
    26 #include "presetcrkeys.h"
       
    27 #include <preset.h>
       
    28 #include "cenrepbookkeeping.h"
       
    29 #include "trace.h"
       
    30 
       
    31 
       
    32 class TChannelIndexList
       
    33     {
       
    34 public:
       
    35     TInt iChannelIndex;
       
    36     TInt iNameIndex;
       
    37     TInt iFrequencyIndex;
       
    38     TInt iUrlIndex;
       
    39     TInt iRestOfParametersIndex;
       
    40     };
       
    41 
       
    42 // ============= STATIC FUNCTIONS ==============
       
    43 
       
    44 static TInt CalculateChannelIndexes( const TInt aChannelIndex,  TChannelIndexList& aChannelIndexList)
       
    45     {
       
    46     FUNC_LOG;
       
    47     TInt err( KErrNone );
       
    48     if ( ( KMaxNumberOfPresetStations <= aChannelIndex ) ||
       
    49             ( 0 >  aChannelIndex ) )
       
    50         {
       
    51         err = KErrArgument;
       
    52         }
       
    53     else
       
    54         {
       
    55         aChannelIndexList.iChannelIndex = 
       
    56          KRadioPresetChannel1 + ( KNbrOfParametersPerChannelSequence * aChannelIndex );
       
    57         aChannelIndexList.iNameIndex =
       
    58             aChannelIndexList.iChannelIndex + KChannelNameOffset;        
       
    59         aChannelIndexList.iFrequencyIndex =
       
    60             aChannelIndexList.iChannelIndex + KFrequencyOffset;        
       
    61         aChannelIndexList.iUrlIndex =
       
    62             aChannelIndexList.iChannelIndex + KUrlOffset;        
       
    63         aChannelIndexList.iRestOfParametersIndex =
       
    64             aChannelIndexList.iChannelIndex + KRestOfParametersOffset;
       
    65         }
       
    66     return err;
       
    67     }
       
    68 
       
    69 // ============= MEMBER FUNCTIONS ==============
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 CCenrepHandler::CCenrepHandler()
       
    76     {
       
    77     FUNC_LOG;
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 void CCenrepHandler::ConstructL()
       
    85     {
       
    86     FUNC_LOG;
       
    87     iCentralRepository = CRepository::NewL( KCRUidPresetUtility );
       
    88     iBookKeeping = new (ELeave) CCenrepBookKeeping;
       
    89     ReadBookKeepingL();
       
    90     }
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 CCenrepHandler* CCenrepHandler::NewL()
       
    97     {
       
    98     FUNC_LOG;
       
    99     CCenrepHandler* self = new (ELeave) CCenrepHandler();
       
   100     CleanupStack::PushL( self );
       
   101     self->ConstructL();
       
   102     CleanupStack::Pop( self );
       
   103     return self;
       
   104     }
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 CCenrepHandler::~CCenrepHandler()
       
   111     {
       
   112     FUNC_LOG;
       
   113     delete iCentralRepository;
       
   114     delete iBookKeeping;
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 TInt CCenrepHandler::MaxPresetCount() const
       
   122     {
       
   123     FUNC_LOG;
       
   124     return KMaxNumberOfPresetStations;
       
   125     }
       
   126 
       
   127 // -----------------------------------------------------------------------------
       
   128 // Get the current number of presets
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 TInt CCenrepHandler::PresetCount() const
       
   132     {
       
   133     FUNC_LOG;
       
   134     return iBookKeeping->PresetCount();
       
   135     }
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // Gets the first preset
       
   139 // -----------------------------------------------------------------------------
       
   140 //
       
   141 TInt CCenrepHandler::FirstPreset() const
       
   142     {
       
   143     FUNC_LOG;
       
   144     return iBookKeeping->FirstIndex();
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // Get the next preset index that has been set, given the current index
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 TInt CCenrepHandler::NextPreset( TInt aFromIndex ) const
       
   152     {
       
   153     FUNC_LOG;
       
   154     return iBookKeeping->NextIndex( aFromIndex );
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // Delete the current preset
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 TInt CCenrepHandler::DeletePreset( TInt aIndex )
       
   162     {
       
   163     FUNC_LOG;
       
   164     TInt err( KErrNone );
       
   165     if ( -1 == aIndex )
       
   166         {
       
   167         // Delete all
       
   168         TChannelIndexList channelIndexList;
       
   169         for (  TInt j( FirstPreset() ); 0 <= j;  j = FirstPreset() )
       
   170             {
       
   171             INFO_1("Deleting index: %i", j );
       
   172             if ( KErrNone == CalculateChannelIndexes( j, channelIndexList ) )
       
   173                 {                
       
   174                 iCentralRepository->Delete( channelIndexList.iNameIndex );    
       
   175                 iCentralRepository->Delete( channelIndexList.iFrequencyIndex );   
       
   176                 iCentralRepository->Delete( channelIndexList.iUrlIndex );
       
   177                 iCentralRepository->Delete( channelIndexList.iRestOfParametersIndex );
       
   178                 iBookKeeping->RemoveIndex( j );        
       
   179                 }
       
   180             }
       
   181         }
       
   182     else
       
   183         {
       
   184         TChannelIndexList channelIndexList;
       
   185         err = CalculateChannelIndexes( aIndex, channelIndexList );
       
   186         if ( KErrNone == err )
       
   187             {
       
   188             iCentralRepository->Delete( channelIndexList.iNameIndex );    
       
   189             iCentralRepository->Delete( channelIndexList.iFrequencyIndex );   
       
   190             iCentralRepository->Delete( channelIndexList.iUrlIndex );
       
   191             iCentralRepository->Delete( channelIndexList.iRestOfParametersIndex );
       
   192             iBookKeeping->RemoveIndex( aIndex );        
       
   193             }
       
   194         }
       
   195     if ( KErrNone == err )
       
   196         {
       
   197         SaveBookKeeping();
       
   198         }
       
   199     return err;
       
   200     }
       
   201 
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 // -----------------------------------------------------------------------------
       
   205 //
       
   206 TInt CCenrepHandler::SavePresetL( const TPreset& aPreset, TInt aIndex )
       
   207     {
       
   208     FUNC_LOG;
       
   209     if ( 0 > aIndex )
       
   210         {
       
   211         aIndex = iBookKeeping->FindUnusedIndex();
       
   212         }
       
   213     if ( 0 > aIndex )
       
   214         {
       
   215         User::Leave( KErrDiskFull ); // Not really a good code for this
       
   216         }
       
   217     TChannelIndexList channelIndexList;
       
   218     User::LeaveIfError( CalculateChannelIndexes( aIndex, channelIndexList) );
       
   219 
       
   220     // First save name to its own key in the key sequence.
       
   221     User::LeaveIfError( iCentralRepository->Set( channelIndexList.iNameIndex, aPreset.Name() ) );
       
   222 
       
   223     // Frequency  to its own key in the key sequence.
       
   224     User::LeaveIfError( iCentralRepository->Set( channelIndexList.iFrequencyIndex, (TInt)aPreset.Frequency() ) );
       
   225 
       
   226     // Url to its own key in the key sequence.
       
   227     User::LeaveIfError( iCentralRepository->Set( channelIndexList.iUrlIndex, aPreset.Url() ) );
       
   228 
       
   229     // Then externalize the rest of the data to a common key.
       
   230     TInt err( KErrNone );
       
   231     TInt length( aPreset.MyExternalizedDataSize() );
       
   232     TUint i ( 1 );
       
   233     INFO_1( "aPreset.MyExternalizedDataSize()=%i", length );
       
   234     for ( TBool cont = ( 0 < length ) ? ETrue : EFalse; (cont); cont = ( KErrOverflow == err ) ?  ETrue : EFalse ) 
       
   235         {
       
   236         HBufC8* buf = HBufC8::NewLC( i * length  );
       
   237         TPtr8 bufPtr = buf->Des();
       
   238         RDesWriteStream outStream( bufPtr );
       
   239         CleanupClosePushL( outStream );
       
   240         TRAP( err, aPreset.ExternalizeL( outStream ) );
       
   241         if ( KErrNone == err )
       
   242             {
       
   243             outStream.CommitL();
       
   244             User::LeaveIfError( iCentralRepository->Set( channelIndexList.iRestOfParametersIndex, *buf ) );
       
   245             }
       
   246         else
       
   247             {
       
   248             INFO_2( "SavePresetL bigger buffer (%i) needed than required by aPreset.MyExternalizedDataSize()=%i", i*length, aPreset.MyExternalizedDataSize() );
       
   249             ++i;
       
   250             }
       
   251         CleanupStack::PopAndDestroy( &outStream );
       
   252         CleanupStack::PopAndDestroy( buf );
       
   253         }
       
   254     User::LeaveIfError( err );
       
   255 
       
   256     iBookKeeping->AddIndex( aIndex );
       
   257     SaveBookKeeping();
       
   258     return aIndex;
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 void CCenrepHandler::ReadPresetL( TInt aIndex, TPreset& aPreset )
       
   266     {
       
   267     FUNC_LOG;
       
   268 
       
   269     // Read name from its own key in the key sequence
       
   270     TChannelIndexList channelIndexList;
       
   271     User::LeaveIfError( CalculateChannelIndexes( aIndex, channelIndexList) );
       
   272     TPresetName tempChannelName;
       
   273     User::LeaveIfError( iCentralRepository->Get(channelIndexList.iNameIndex, tempChannelName ) );
       
   274     aPreset.SetName( tempChannelName );
       
   275 
       
   276     // Read frequency from its own key in the key sequence
       
   277     TInt frequency( 0 );
       
   278     User::LeaveIfError( iCentralRepository->Get( channelIndexList.iFrequencyIndex, frequency ) );
       
   279     aPreset.SetFrequency( frequency );
       
   280 
       
   281     // Read url from its own key in the key sequence
       
   282     TRadioUrl tempUrlName;
       
   283     TInt err = iCentralRepository->Get( channelIndexList.iUrlIndex, tempUrlName );
       
   284     if ( KErrNone == err )
       
   285         {        
       
   286         aPreset.SetUrl( tempUrlName );
       
   287         }
       
   288     else if ( KErrNotFound == err )
       
   289         {
       
   290         // This is an optional parameter.
       
   291         }
       
   292     else
       
   293         {
       
   294         User::Leave( err );
       
   295         }
       
   296                       
       
   297 
       
   298     // Then use the below code to internalize rest of parameters from the common key
       
   299     TInt actualLength( aPreset.MyExternalizedDataSize() );
       
   300     INFO_1( "ReadPresetL aPreset.MyExternalizedDataSize()=%i", actualLength );
       
   301     for ( TBool cont = ( 0 < actualLength ) ? ETrue : EFalse; (cont); cont = ( KErrOverflow == err ) ?  ETrue : EFalse ) 
       
   302         {
       
   303         HBufC8* buf = HBufC8::NewLC( actualLength );
       
   304         TPtr8 bufPtr = buf->Des();
       
   305         err = iCentralRepository->Get( channelIndexList.iRestOfParametersIndex, bufPtr, actualLength );
       
   306         if ( ( KErrNone == err ) && ( 0 < buf->Length() ) )
       
   307             {
       
   308             RDesReadStream inStream;
       
   309             inStream.Open( *buf );
       
   310             CleanupClosePushL( inStream );       
       
   311             aPreset.InternalizeL( inStream );        
       
   312             CleanupStack::PopAndDestroy( &inStream );
       
   313             }
       
   314         else if ( KErrNotFound == err )
       
   315             {
       
   316             // This is not filled by CT tool even though name, frequency and URL might be 
       
   317             // filled for the current channel. Don't leave.
       
   318             INFO_1( "ReadPresetL KErrNotFound, key=%i", channelIndexList.iRestOfParametersIndex );
       
   319             }
       
   320         else if ( KErrOverflow == err )
       
   321             {
       
   322             INFO_2( "ReadPresetL KErrOverflow, buf->Length()=%i actualLength=%i", buf->Length(), actualLength );
       
   323             // Trying again with actual with buffer that can store the whole key
       
   324             }
       
   325         else
       
   326             {
       
   327             User::Leave( err );
       
   328             }
       
   329         CleanupStack::PopAndDestroy(buf);
       
   330         } // for (;;) 
       
   331     }
       
   332 
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 void CCenrepHandler::ReadBookKeepingL()
       
   338     {
       
   339     FUNC_LOG;
       
   340     TPtr8 bufPtr = iBookKeeping->BookKeepingData();
       
   341 
       
   342     TInt err( iCentralRepository->Get( KRadioBookKeepingLocation, bufPtr ) );
       
   343     if ( KErrNotFound == err )
       
   344         {
       
   345         // Bookkeeping does not exist. Search possible preconfigured channels.
       
   346         ReadPreDefinedPresetsL();
       
   347         err = KErrNone;
       
   348         }
       
   349     User::LeaveIfError( err );
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 void CCenrepHandler::SaveBookKeeping()
       
   357     {
       
   358     FUNC_LOG;
       
   359     TInt err( iCentralRepository->Set( KRadioBookKeepingLocation, iBookKeeping->BookKeepingData() ) );
       
   360     if ( KErrNone !=  err )
       
   361         {
       
   362         INFO_1("Saving of BookKeeping failed with error: %i ", err)
       
   363         // It is better to destroy data that is out of sync
       
   364         iCentralRepository->Delete( KRadioBookKeepingLocation );
       
   365         // Go on with local bookkeeping data
       
   366         }
       
   367     }
       
   368 
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 void CCenrepHandler::ReadPreDefinedPresetsL()
       
   374     {
       
   375     FUNC_LOG;
       
   376     TInt frequency ( 0 );
       
   377     TInt err( KErrNone );
       
   378     TChannelIndexList channelIndexList;
       
   379     iBookKeeping->Clear();
       
   380     for(TInt index = 0; index < KMaxNumberOfPresetStations; index++)
       
   381         {
       
   382         User::LeaveIfError( CalculateChannelIndexes( index, channelIndexList) );
       
   383         err = iCentralRepository->Get( channelIndexList.iFrequencyIndex, frequency );
       
   384         if ( KErrNone ==  err )
       
   385             {
       
   386             iBookKeeping->AddIndex( index );
       
   387             }
       
   388         } 
       
   389     SaveBookKeeping();
       
   390     }