featuremgmt/featuremgr/src/serverexe/featmgrfeatureregistry.cpp
changeset 0 08ec8eefde2f
child 9 667e88a979d7
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <ecom/ecom.h>
       
    21 #include <e32uid.h>
       
    22 #include <f32file.h>
       
    23 #include <e32property.h>
       
    24 #include <sacls.h>
       
    25 #include "featmgrconfiguration.h"
       
    26 #include "featmgrfeatureregistry.h"
       
    27 #include "featmgrserver.h"
       
    28 #include "featmgrdebug.h"
       
    29 
       
    30 #define MAXSWIOPS 50
       
    31 #define SWITIMEOUT 15000000
       
    32 
       
    33 // CONSTANTS
       
    34 _LIT( KZFeaturesFileNameMatch, "feature*" );
       
    35 _LIT( KCRuntimeFeaturesFileName, "features.dat" );
       
    36 #ifdef EXTENDED_FEATURE_MANAGER_TEST
       
    37 _LIT( KZFeaturesDir, "C:\\Private\\102836E5\\" );
       
    38 _LIT( KCFeatMgrPrivatePath, "?:\\Private\\102836E5\\runtime\\" );
       
    39 #else
       
    40 _LIT( KZFeaturesDir, "Z:\\Private\\10205054\\" );
       
    41 _LIT( KCFeatMgrPrivatePath, "?:\\Private\\10205054\\" );
       
    42 #endif // EXTENDED_FEATURE_MANAGER_TEST
       
    43 
       
    44 const TUint32 KDefaultData( 0x00000000 );
       
    45 // Feature file header constants. 
       
    46 // First 4 bytes of config file: ASCII f-e-a-t followed by file version and flags.
       
    47 const TUint32 KFileType( 0x74616566 );
       
    48 const TUint16 KFileVersion( 1 );
       
    49 const TUint16 KFileFlags( 0 );
       
    50 
       
    51 
       
    52 // ============================= LOCAL FUNCTIONS ===============================
       
    53 
       
    54 // ============================ MEMBER FUNCTIONS ===============================
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CFeatMgrFeatureRegistry::CFeatMgrFeatureRegistry
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CFeatMgrFeatureRegistry::CFeatMgrFeatureRegistry( RFs& aFs,
       
    61     MFeatMgrRegistryObserver& aObserver  )
       
    62     :
       
    63     iObserver( aObserver ),
       
    64     iFs( aFs ),
       
    65     iSWICacheFeature( EFalse ),
       
    66     iSWIStatus( ESWIComplete ),
       
    67     iSWIProcessId( 1 ),
       
    68     iOomOccured(EFalse)
       
    69     {
       
    70     }
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // CFeatMgrFeatureRegistry::ConstructL
       
    74 // Symbian 2nd phase constructor can leave.
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 void CFeatMgrFeatureRegistry::ConstructL()
       
    78     {
       
    79     }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CFeatMgrFeatureRegistry::NewL
       
    83 // Two-phased constructor.
       
    84 // -----------------------------------------------------------------------------
       
    85 //
       
    86 CFeatMgrFeatureRegistry* CFeatMgrFeatureRegistry::NewL( RFs& aFs, 
       
    87     MFeatMgrRegistryObserver& aObserver )
       
    88     {
       
    89     CFeatMgrFeatureRegistry* self = 
       
    90         new( ELeave ) CFeatMgrFeatureRegistry( aFs, aObserver );
       
    91     
       
    92     CleanupStack::PushL( self );
       
    93     self->ConstructL();
       
    94     CleanupStack::Pop( self );
       
    95 
       
    96     return self;
       
    97     }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // Destructor
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 CFeatMgrFeatureRegistry::~CFeatMgrFeatureRegistry()
       
   104     {
       
   105     FUNC_LOG
       
   106     
       
   107     iFeatureList.Close();
       
   108     iRangeList.Close();
       
   109     iFeatureListBackup.Close();    
       
   110     iSWICachedOperations.Close();
       
   111     if( iSWIListener )
       
   112     	{
       
   113         delete iSWIListener;    	
       
   114     	}
       
   115     if( iSWITimer )
       
   116     	{
       
   117     	delete iSWITimer;
       
   118     	}
       
   119     }
       
   120 
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CFeatMgrFeatureRegistry::IsFeatureSupported
       
   124 // -----------------------------------------------------------------------------
       
   125 //  
       
   126 TInt CFeatMgrFeatureRegistry::IsFeatureSupported( TFeatureServerEntry& aFeature )
       
   127     {
       
   128     TInt err( KErrNotFound );
       
   129     const TInt index = SearchFeature( aFeature.FeatureUid() );
       
   130     
       
   131     if ( index == KErrNotFound )
       
   132         {
       
   133         // Check whether feature in supported ranges
       
   134         TInt count( iRangeList.Count() );
       
   135         TUid uid( aFeature.FeatureUid() );
       
   136         for( TInt i = 0; i < count; i++ )
       
   137             {
       
   138             if( (uid.iUid >= iRangeList[i].iLowUid.iUid) && 
       
   139                 (uid.iUid <= iRangeList[i].iHighUid.iUid) )
       
   140                 {
       
   141                 TBitFlags32 flags( 0 );
       
   142                 flags.Assign( EFeatureSupported, KFeatureSupported );
       
   143                 TFeatureServerEntry entry( aFeature.FeatureUid(), flags, KDefaultData );
       
   144                 aFeature = entry;
       
   145                 err = KFeatureSupported;
       
   146                 break;
       
   147                 }
       
   148             }
       
   149         }
       
   150     else if( IsFlagSet( index, EFeatureUninitialized ) )
       
   151         {
       
   152         // Supported status bit is not taken into account if feature not yet initialized
       
   153         err = KErrNotReady;
       
   154         }
       
   155     else if ( (index < iFeatureList.Count()) && IsFlagSet( index, EFeatureSupported ) )
       
   156         {
       
   157         TBitFlags32 flags = iFeatureList[index].FeatureFlags();
       
   158         flags.Assign( EFeatureSupported, KFeatureSupported );
       
   159         TUint32 data = iFeatureList[index].FeatureData();
       
   160         TFeatureServerEntry entry( aFeature.FeatureUid(), flags, data );
       
   161         aFeature = entry;
       
   162         err = KFeatureSupported;
       
   163         }
       
   164     else
       
   165         {
       
   166         err = KFeatureUnsupported;
       
   167         }
       
   168 
       
   169     return err;
       
   170     }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CFeatMgrFeatureRegistry::AddFeature
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 TInt CFeatMgrFeatureRegistry::AddFeature( TFeatureServerEntry& aFeature, TUint aPrcId )
       
   177     {
       
   178     TInt err( KErrAccessDenied );
       
   179     
       
   180     if( iSWIProcessId == aPrcId && iSWICacheFeature )
       
   181 		{
       
   182 		err = SWICacheCommand(ESWIAddFeat, aFeature);
       
   183 		}
       
   184     else
       
   185     	{
       
   186         const TInt index = SearchFeature( aFeature.FeatureUid() );
       
   187 	
       
   188 	    if ( index == KErrNotFound )
       
   189 	        {
       
   190 	        TBitFlags32 flags( aFeature.FeatureFlags() );
       
   191 	        flags.Set( EFeatureRuntime );
       
   192 	
       
   193 	        //Check the feature falg is valid
       
   194 	        TRAP(err, err = ValidateRuntimeFeatureFlagL(flags));
       
   195 	        if (err != KErrNone)
       
   196 	            return err;
       
   197 	
       
   198 	        TFeatureServerEntry entry( aFeature.FeatureUid(), flags, aFeature.FeatureData() );	       
       
   199 			err = iFeatureList.InsertInOrder( entry, FindByUid );
       
   200 	        if ( err == KErrNone )
       
   201 	            {
       
   202 	            TFeatureChangeType changeType( EFeatureFeatureCreated );
       
   203 	            err = HandleChange( entry, changeType );
       
   204 	            }
       
   205 	        }
       
   206 	    else
       
   207 	        {
       
   208 	        err = KErrAlreadyExists;
       
   209 	        }
       
   210 	    
       
   211 	    INFO_LOG("CFeatMgrFeatureRegistry::AddFeature - Features directly stored in registry");
       
   212     	}
       
   213     
       
   214     LOG_IF_ERROR1( err, "CFeatMgrFeatureRegistry::AddFeature - result %d", err );
       
   215 
       
   216     return err;
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CFeatMgrFeatureRegistry::DeleteFeature
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 TInt CFeatMgrFeatureRegistry::DeleteFeature( TUid aFeature, TUint aPrcId  )
       
   224     {
       
   225     TInt err( KErrAccessDenied );
       
   226 	
       
   227     if( iSWIProcessId == aPrcId && iSWICacheFeature )
       
   228     	{
       
   229     	err = SWICacheCommand(ESWIDeleteFeat, aFeature);
       
   230     	}
       
   231     else
       
   232     	{
       
   233 	    // Check if the feature is runtime
       
   234 	    TInt index = SearchFeature( aFeature );
       
   235 	    if ( index == KErrNotFound )
       
   236 	        {
       
   237 	        return KErrNotFound;
       
   238 	        }
       
   239 	    if ( !iFeatureList[index].FeatureFlags().IsSet(EFeatureRuntime) )
       
   240 	        {
       
   241 	        return KErrAccessDenied;
       
   242 	        }
       
   243 	
       
   244 	    TFeatureServerEntry entry = iFeatureList[index];
       
   245 	    
       
   246     	iFeatureList.Remove( index );
       
   247         TFeatureChangeType changeType( EFeatureFeatureDeleted );
       
   248         err = HandleChange( entry, changeType );
       
   249         
       
   250         INFO_LOG("CFeatMgrFeatureRegistry::DeleteFeature - Features deleted directly from registry");
       
   251         }
       
   252     
       
   253     LOG_IF_ERROR1( err, "CFeatMgrFeatureRegistry::DeleteFeature - result %d", err );
       
   254     
       
   255     return err;
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CFeatMgrFeatureRegistry::SetFeature
       
   260 //This method cannot set feature flag range in DSR unless it is added to before
       
   261 //using CFeatMgrFeatureRegistry::AddFeature()
       
   262 // -----------------------------------------------------------------------------
       
   263 //	
       
   264 TInt CFeatMgrFeatureRegistry::SetFeature( TUid aFeature, TInt aEnable, const TUint32 *aData, TUint aPrcId  )
       
   265     {
       
   266     FUNC_LOG
       
   267 
       
   268     TInt err( KErrNone );
       
   269     
       
   270     if( iSWIProcessId == aPrcId && iSWICacheFeature )
       
   271     	{
       
   272 		TBitFlags32 flags(0);
       
   273     	flags.Assign( EFeatureSupported, aEnable );
       
   274     	TFeatureServerEntry entry( aFeature, flags, *aData );    
       
   275 	    err = SWICacheCommand(ESWISetFeatAndData, entry);
       
   276     	}
       
   277     else 
       
   278     	{
       
   279 	    TInt index;
       
   280 	
       
   281 	    // Validate feature exists and is modifiable
       
   282 	    err = ValidateFeature( aFeature, index );
       
   283 	
       
   284 	    if ( err != KErrNone )
       
   285 	        {
       
   286 			return err;
       
   287 	        }
       
   288 	
       
   289 	    if ( (index >= 0 && index < iFeatureList.Count()) )
       
   290 	        {
       
   291         	TBitFlags32 flags = iFeatureList[index].FeatureFlags();
       
   292 	        TUint32 data = iFeatureList[index].FeatureData();
       
   293 	        TFeatureChangeType changeType( EFeatureStatusUpdated );
       
   294 
       
   295 	        // Update "supported" info according to request
       
   296 	        if( (aEnable == EFeatureSupportEnable) || (aEnable == EFeatureSupportDisable) )
       
   297 	            {
       
   298 	            INFO_LOG1( "CFeatMgrFeatureRegistry::SetFeature() - aEnable %d", aEnable );
       
   299 	            flags.Assign( EFeatureSupported, aEnable );
       
   300 	            }
       
   301 	        // When setting feature, always unset "uninitialized" bit
       
   302 	        flags.Assign( EFeatureUninitialized, 0 );
       
   303 
       
   304 	        // Update data whenever applied
       
   305 	        if( aData )
       
   306 	            {
       
   307 	            INFO_LOG1( "CFeatMgrFeatureRegistry::SetFeature() - aData %d", aData );
       
   308 	            data = *aData;
       
   309 
       
   310 	            if( aEnable == EFeatureSupportUntouch )
       
   311 	                {
       
   312 	                changeType = EFeatureDataUpdated;
       
   313 	                }
       
   314 	            else
       
   315 	                {
       
   316 	                changeType = EFeatureStatusDataUpdated;
       
   317 	                }
       
   318 	            }
       
   319 
       
   320 	        TFeatureServerEntry entry( aFeature, flags, data );
       
   321 	        //Check if the feature will actually change
       
   322 	        if(iFeatureList[index].FeatureFlags() == flags && iFeatureList[index].FeatureData() == data )
       
   323 	        	{
       
   324 	        	//No change were made, set change type to EFeatureNoChange
       
   325 	        	changeType = EFeatureNoChange;
       
   326 	        	}
       
   327 	        else
       
   328 	        	{
       
   329 	        	// Set the feature entry in list with updated information
       
   330 	        	iFeatureList[index].Set(entry);
       
   331 	        	}
       
   332 
       
   333 	        err = HandleChange( entry, changeType );
       
   334 	        }
       
   335     	}
       
   336     
       
   337     LOG_IF_ERROR1( err, "CFeatMgrFeatureRegistry::SetFeature - result %d", err );
       
   338 
       
   339     return err;
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CFeatMgrFeatureRegistry::HandleChange
       
   344 // -----------------------------------------------------------------------------
       
   345 //  
       
   346 TInt CFeatMgrFeatureRegistry::HandleChange( TFeatureServerEntry& aFeature, 
       
   347     TFeatureChangeType aType )
       
   348     {
       
   349     FUNC_LOG
       
   350     
       
   351     TInt err( KErrNone );
       
   352     
       
   353     // Update feature file, when feature is specified as persisted.
       
   354     if ( aFeature.FeatureFlags().IsSet( EFeaturePersisted ) )
       
   355         {
       
   356         TRAP( err, UpdateRuntimeFeaturesFileL( aFeature, aType ) );
       
   357         LOG_IF_ERROR1( err, "CFeatMgrFeatureRegistry::HandleChange - update error %d", err );
       
   358     
       
   359         // It is questionnable whether we should remove the feature from iFeatureList.
       
   360         // However, feature is usable until device is powered down and features reloaded.
       
   361         // if ( err == KErrNone )
       
   362         }
       
   363     
       
   364     // It is also questionnable whether we should suppress notification in case file 
       
   365     // update failed.
       
   366     // if ( err == KErrNone )
       
   367     iObserver.HandleFeatureChange( aFeature, aType );
       
   368     
       
   369     return err;
       
   370     }
       
   371     
       
   372 // -----------------------------------------------------------------------------
       
   373 // CFeatMgrFeatureRegistry::ValidateFeature
       
   374 // -----------------------------------------------------------------------------
       
   375 //  
       
   376 TInt CFeatMgrFeatureRegistry::ValidateFeature( TUid aFeature, TInt &aIndex )
       
   377     {
       
   378     TInt err( KErrNone );
       
   379     
       
   380     aIndex = SearchFeature( aFeature );
       
   381      
       
   382     if ( aIndex == KErrNotFound )
       
   383         {
       
   384         err = KErrNotFound;
       
   385         }
       
   386     else if ( !IsFlagSet( aIndex, EFeatureModifiable ) )
       
   387         {
       
   388         err = KErrAccessDenied;
       
   389         }
       
   390     
       
   391     return err;
       
   392     }
       
   393     
       
   394 // -----------------------------------------------------------------------------
       
   395 // CFeatMgrFeatureRegistry::FindByUid
       
   396 // Returns Zero if UIDs do match.
       
   397 // -----------------------------------------------------------------------------
       
   398 //  
       
   399 TInt CFeatMgrFeatureRegistry::FindByUid( const TUid *aFeature, 
       
   400     const TFeatureServerEntry& aItem )
       
   401     {
       
   402     if ( aFeature->iUid < aItem.FeatureUid().iUid )
       
   403         {
       
   404         return -1;
       
   405         }
       
   406     else if ( aFeature->iUid > aItem.FeatureUid().iUid )
       
   407         {
       
   408         return 1;
       
   409         }
       
   410 
       
   411     return 0;
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CFeatMgrFeatureRegistry::FindByUid
       
   416 // Returns Zero if UIDs do match.
       
   417 // -----------------------------------------------------------------------------
       
   418 //  
       
   419 TInt CFeatMgrFeatureRegistry::FindByUid( const TFeatureServerEntry& aFeature, 
       
   420     const TFeatureServerEntry& aItem )
       
   421     {
       
   422     if ( aFeature.FeatureUid().iUid < aItem.FeatureUid().iUid )
       
   423         {
       
   424         return -1;
       
   425         }
       
   426     else if ( aFeature.FeatureUid().iUid > aItem.FeatureUid().iUid )
       
   427         {
       
   428         return 1;
       
   429         }
       
   430 
       
   431     return 0;
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CFeatMgrFeatureRegistry::SearchFeature
       
   436 // -----------------------------------------------------------------------------
       
   437 //  
       
   438 TInt CFeatMgrFeatureRegistry::SearchFeature( TUid aFeature )
       
   439     {
       
   440     const TUid& uid( aFeature );
       
   441     return iFeatureList.FindInOrder( uid, FindByUid );
       
   442     }
       
   443     
       
   444 // -----------------------------------------------------------------------------
       
   445 // CFeatMgrFeatureRegistry::IsFlagSet
       
   446 // -----------------------------------------------------------------------------
       
   447 //  
       
   448 TBool CFeatMgrFeatureRegistry::IsFlagSet( TInt aIndex, TFeatureFlags aFlag )
       
   449     {
       
   450     TBool isSet( EFalse );
       
   451     if( aIndex < iFeatureList.Count() )
       
   452         {
       
   453         isSet = iFeatureList[aIndex].FeatureFlags().IsSet(aFlag);
       
   454         }
       
   455         
       
   456     return isSet;
       
   457     }
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // CFeatMgrFeatureRegistry::SupportedFeatures
       
   461 // -----------------------------------------------------------------------------
       
   462 //  
       
   463 void CFeatMgrFeatureRegistry::SupportedFeaturesL( RFeatureUidArray& aSupportedFeatures )
       
   464     {
       
   465     FUNC_LOG
       
   466     
       
   467     TInt count = iFeatureList.Count();
       
   468     
       
   469     for ( TInt i = 0; i < count; i++ )
       
   470         {
       
   471         if( IsFlagSet( i, EFeatureSupported) )
       
   472             {
       
   473             aSupportedFeatures.AppendL( iFeatureList[i].FeatureUid() );
       
   474             }
       
   475         }
       
   476     }
       
   477 
       
   478 // -----------------------------------------------------------------------------
       
   479 // CFeatMgrFeatureRegistry::NumberOfSupportedFeatures
       
   480 // -----------------------------------------------------------------------------
       
   481 //  
       
   482 TInt CFeatMgrFeatureRegistry::NumberOfSupportedFeatures()
       
   483     {
       
   484     FUNC_LOG
       
   485     
       
   486     TInt count = iFeatureList.Count();
       
   487     TInt countSupported(0);
       
   488     
       
   489     for ( TInt i = 0; i < count; i++ )
       
   490         {
       
   491         if( IsFlagSet( i, EFeatureSupported) )
       
   492             {
       
   493             countSupported++;
       
   494             }
       
   495         }
       
   496     
       
   497     return countSupported;
       
   498     }
       
   499 
       
   500 // -----------------------------------------------------------------------------
       
   501 
       
   502 TInt CFeatMgrFeatureRegistry::ResetFeatures()
       
   503     {
       
   504     FUNC_LOG
       
   505     
       
   506     // backup the feature list before it is destroyed
       
   507     iFeatureListBackup.Reset();
       
   508     TInt count = iFeatureList.Count();
       
   509     
       
   510     for( TInt i=0; i < count; i++ )
       
   511         {
       
   512         iFeatureListBackup.Append( iFeatureList[i] );
       
   513         }
       
   514     
       
   515     // destroy the feature list
       
   516     iFeatureList.Reset();
       
   517     iFeatureList.Close();
       
   518     
       
   519     iRangeList.Reset();
       
   520     iRangeList.Close();
       
   521 
       
   522     return( 0 );
       
   523     }
       
   524 
       
   525 /**
       
   526  * Get the fully qualified path and filename to the features.dat
       
   527  * data file.
       
   528  */ 
       
   529 TFileName CFeatMgrFeatureRegistry::GetFeaturesFilePathAndName( void )
       
   530 	{
       
   531     TFileName path( KCFeatMgrPrivatePath );
       
   532 
       
   533     path[0] = iFs.GetSystemDriveChar();
       
   534     path.Append( KCRuntimeFeaturesFileName );
       
   535 
       
   536     return path;
       
   537 	}
       
   538 
       
   539 // CFeatMgrFeatureRegistry::ReadFeatureFilesL
       
   540 // Reads platform and product feature files. 
       
   541 // -----------------------------------------------------------------------------
       
   542 //  
       
   543 void CFeatMgrFeatureRegistry::ReadFeatureFilesL()
       
   544     {
       
   545     FUNC_LOG    
       
   546     
       
   547     // Read feature files from Z
       
   548     ReadFilesFromDirL( KZFeaturesDir );
       
   549 
       
   550     //check that there is at least one DSR 
       
   551     if (!iRangeList.Count()) 
       
   552     	{
       
   553     	_LIT( KPanicCategory, "FeatMgrServer" );
       
   554     	ERROR_LOG( "CFeatMgrFeatureRegistry::ReadFilesFromDirL() - no DSR found in ROM; this indicates a system integration error  - going to panic" );
       
   555     	User::Panic( KPanicCategory, EPanicNoDSR );    
       
   556     	}
       
   557     }
       
   558 
       
   559 // -----------------------------------------------------------------------------
       
   560 // CFeatMgrFeatureRegistry::ReadFilesFromDirL
       
   561 // -----------------------------------------------------------------------------
       
   562 //
       
   563 void CFeatMgrFeatureRegistry::ReadFilesFromDirL( const TDesC& aDirName )
       
   564     {
       
   565 	_LIT( KPanicCategory, "FEATMGR-READFILE" );
       
   566 
       
   567     CDir* dir = NULL; 
       
   568     TInt err( KErrNone );
       
   569 
       
   570     err = iFs.GetDir( aDirName, KEntryAttNormal, ESortByName, dir );
       
   571     CleanupStack::PushL( dir );
       
   572 
       
   573     if( err == KErrNone )
       
   574         {
       
   575         err = ReadFiles( aDirName, dir );
       
   576         if ( err != KErrNone )
       
   577             {            
       
   578             ERROR_LOG1( "CFeatMgrFeatureRegistry::ReadFilesFromDirL() - err %d ", err );
       
   579             User::Leave( err );    
       
   580             }
       
   581         }  
       
   582     else if( err == KErrPathNotFound )
       
   583     	{
       
   584     	__ASSERT_ALWAYS( EFalse, User::Panic( KPanicCategory, EPanicNoFeatureFiles) );
       
   585     	}
       
   586 	else
       
   587         {            
       
   588         ERROR_LOG1( "CFeatMgrFeatureRegistry::ReadFilesFromDirL() - err %d ", err );
       
   589         User::Leave( err );    
       
   590         }
       
   591     
       
   592     CleanupStack::PopAndDestroy( dir );
       
   593     }
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CFeatMgrFeatureRegistry::ReadRuntimeFeaturesL
       
   597 // -----------------------------------------------------------------------------
       
   598 //
       
   599 void CFeatMgrFeatureRegistry::ReadRuntimeFeaturesL( TBool &aFeaturesReady )
       
   600     {
       
   601     TFileName path( KCFeatMgrPrivatePath );
       
   602     path[0] = iFs.GetSystemDriveChar();
       
   603     path.Append( KCRuntimeFeaturesFileName );
       
   604 
       
   605     TInt err( KErrNone );
       
   606     TRAP( err, ReadFileL( path ) );
       
   607 
       
   608     if ((err == KErrCorrupt) || (err == KErrArgument))
       
   609     	{
       
   610     	iFs.Delete(path);
       
   611     	aFeaturesReady = ETrue;
       
   612     	}
       
   613     else if ( err != KErrNone && err != KErrNotFound && err != KErrPathNotFound )
       
   614         {  
       
   615         ERROR_LOG1( "CFeatMgrFeatureRegistry::ReadRuntimeFeatures - ReadFileL returned err %d", err );
       
   616         User::Leave( err );
       
   617         }
       
   618     else
       
   619         {
       
   620         aFeaturesReady = ETrue;
       
   621         }
       
   622     }
       
   623 
       
   624 // -----------------------------------------------------------------------------
       
   625 // CFeatMgrFeatureRegistry::ReadFiles
       
   626 // -----------------------------------------------------------------------------
       
   627 //  
       
   628 TInt CFeatMgrFeatureRegistry::ReadFiles( const TDesC& aPath, CDir* aDir )
       
   629     {
       
   630     TInt fileCount = aDir->Count();
       
   631     TFileName fileName;
       
   632     TInt err( KErrNotFound );
       
   633     
       
   634     for ( TInt file = 0; file < fileCount; file++ )
       
   635         {
       
   636         TInt match = (*aDir)[file].iName.MatchC( KZFeaturesFileNameMatch );
       
   637         if( match != KErrNotFound )
       
   638             {
       
   639             fileName.Copy(aPath);
       
   640             fileName.Append((*aDir)[file].iName);
       
   641 
       
   642             INFO_LOG1( "CFeatMgrFeatureRegistry::ReadFiles - file: %S", &fileName );
       
   643             TRAP( err, ReadFileL( fileName ) );
       
   644             LOG_IF_ERROR2( err, "CFeatMgrFeatureRegistry::ReadFiles - file: %S, err %d", 
       
   645                 &fileName, err );
       
   646             
       
   647             // Return error if reading of any feature file fails.
       
   648             if( err != KErrNone )
       
   649                 {
       
   650                 break;
       
   651                 }
       
   652             }
       
   653         }
       
   654 
       
   655     return( err );
       
   656     }
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // CFeatMgrFeatureRegistry::ReadFileL
       
   660 // -----------------------------------------------------------------------------
       
   661 //  
       
   662 void CFeatMgrFeatureRegistry::ReadFileL( const TDesC& aFullPath )
       
   663     {
       
   664     FUNC_LOG
       
   665    
       
   666     TUint32 count;
       
   667  	RFileReadStream readStream;
       
   668 
       
   669  	// Open the file and attach to stream 
       
   670     User::LeaveIfError( readStream.Open( iFs, aFullPath, EFileRead ) );
       
   671     CleanupClosePushL( readStream );
       
   672     TUint32 countDSRs;
       
   673     
       
   674     //Validate the header
       
   675     ValidateHeaderL( readStream, count, countDSRs );
       
   676 
       
   677     RArray<TFeatureServerEntry> tempFeatureArray;
       
   678     CleanupClosePushL( tempFeatureArray );
       
   679     
       
   680     //Find the directory that the feature file is contained in. 
       
   681     TFileName dirName(aFullPath);
       
   682     TChar toFind = '\\';
       
   683     dirName.Delete((dirName.LocateReverse(toFind)+1), dirName.Length() );
       
   684     TBool runtimeFile = EFalse;
       
   685     if (dirName.Compare(KZFeaturesDir) != 0) //Location of the feature file.
       
   686     	{
       
   687     	runtimeFile = ETrue;
       
   688     	}
       
   689     
       
   690     tempFeatureArray.ReserveL(count);
       
   691     
       
   692 	for(TInt i = 0; i < count; i++)
       
   693         {
       
   694         TFeatureServerEntry entry;
       
   695         entry.InternalizeL( readStream );
       
   696         
       
   697         //Check for feature flag errors
       
   698         TBitFlags32 flags =  entry.FeatureFlags();
       
   699         TInt err = KErrNone;
       
   700         
       
   701         //Validate the flags
       
   702         // This validation is done in this read function because the validation functions used
       
   703         // are called in other places were this validation is not appropriate. 
       
   704         if (runtimeFile)
       
   705         	{
       
   706         	if (!flags.IsSet(EFeatureRuntime)) //Check to see if the Runtime flag is set if it is not then the feature should have been read in from the rom. 
       
   707         		{
       
   708         		if (SearchFeature( entry.FeatureUid() ) == KErrNotFound )// Check to see if the feature has been read in previously from the rom.
       
   709         			{
       
   710         			User::Leave(KErrCorrupt); 
       
   711         			}
       
   712         		else //The feature has not been read in previously from the rom file and is therefore invalid. The file is deemed to be corrupt
       
   713         			{
       
   714         			ValidateRuntimeFeatureFlagL(flags);   
       
   715             		}
       
   716         		}
       
   717         	else //Flag set the feature is runtime this is then validated as normal
       
   718         		{
       
   719         		ValidateRuntimeFeatureFlagL(flags);    	
       
   720         		}
       
   721 
       
   722         	}
       
   723         else //File is not as runtime file.
       
   724         	{
       
   725         	err = ValidateFeatureFlag(flags);
       
   726         	}
       
   727         
       
   728         //If a feature flag defined in system drive (c:) is invalid, it will not be added to Feature Manager 
       
   729         if ( (err != KErrNone) && flags.IsSet(EFeatureRuntime) )
       
   730         	{
       
   731         	continue;
       
   732        		}
       
   733         
       
   734         tempFeatureArray.Insert( entry, i);
       
   735         
       
   736         }
       
   737 
       
   738     // Reserve memory if list still empty
       
   739     if( !iFeatureList.Count() )
       
   740         {
       
   741         iFeatureList.ReserveL( tempFeatureArray.Count() );
       
   742         }
       
   743 
       
   744     // Read features from temp array
       
   745     for(TInt i = 0; i < tempFeatureArray.Count(); i++)
       
   746         {
       
   747         TFeatureServerEntry entry = tempFeatureArray[i];
       
   748  
       
   749         TInt index = SearchFeature( entry.FeatureUid() );
       
   750         
       
   751         if( index == KErrNotFound)
       
   752             {
       
   753             User::LeaveIfError( iFeatureList.InsertInOrder( entry, FindByUid ) );
       
   754             }
       
   755         else
       
   756             {
       
   757             INFO_LOG1( "CFeatMgrFeatureRegistry::ReadFileL - replacing uid 0x%08x",
       
   758                 iFeatureList[index].FeatureUid().iUid );
       
   759             // Set the feature if it is not previously blacklisted
       
   760             if ( !IsFlagSet( index, EFeatureBlackListed ) )
       
   761                 {
       
   762                 iFeatureList[index].Set(entry);
       
   763                 }
       
   764             }
       
   765         }
       
   766     
       
   767     // Reserve memory if DSR list still empty
       
   768     if( !iRangeList.Count() )
       
   769         {
       
   770         iRangeList.ReserveL( countDSRs );
       
   771         }
       
   772     
       
   773     // Read default supported ranges from file
       
   774     for(TInt i = 0; i < countDSRs; i++)
       
   775         {
       
   776         TDefaultRange range;
       
   777         range.iLowUid = TUid::Uid( readStream.ReadUint32L() );
       
   778         range.iHighUid = TUid::Uid( readStream.ReadUint32L() );
       
   779         iRangeList.AppendL( range );
       
   780         if( iRangeList[i].iLowUid.iUid > iRangeList[i].iHighUid.iUid )
       
   781             {
       
   782             ERROR_LOG( "CFeatMgrFeatureRegistry::ReadFileL - invalid supported range" );
       
   783             iRangeList.Remove( i );
       
   784             User::Leave( KErrCorrupt );
       
   785             }
       
   786         }
       
   787 
       
   788 #if defined(FEATMGR_INFO_LOG_ENABLED)
       
   789     count = iFeatureList.Count();
       
   790     INFO_LOG1( "CFeatMgrFeatureRegistry::ReadFileL - feature entries: %d", count );
       
   791     for(TInt i = 0; i < count; i++)
       
   792         {
       
   793         INFO_LOG3( "CFeatMgrFeatureRegistry::ReadFileL - uid 0x%08x, flags %d, data %d",
       
   794             iFeatureList[i].FeatureUid().iUid, iFeatureList[i].FeatureFlags().iFlags, 
       
   795             iFeatureList[i].FeatureData() );
       
   796         }
       
   797 
       
   798     count = iRangeList.Count();
       
   799     INFO_LOG1( "CFeatMgrFeatureRegistry::ReadFileL - supported ranges: %d", count );
       
   800     for(TInt i = 0; i < count; i++)
       
   801         {
       
   802         INFO_LOG2( "CFeatMgrFeatureRegistry::ReadFileL - low 0x%08x, high 0x%08x",
       
   803             iRangeList[i].iLowUid, iRangeList[i].iHighUid );
       
   804         }
       
   805 #endif
       
   806 
       
   807     CleanupStack::PopAndDestroy( &tempFeatureArray);
       
   808     CleanupStack::PopAndDestroy( &readStream );
       
   809 
       
   810     }
       
   811 
       
   812 // -----------------------------------------------------------------------------
       
   813 // CFeatMgrFeatureRegistry::ValidateHeaderL
       
   814 // -----------------------------------------------------------------------------
       
   815 //  
       
   816 void CFeatMgrFeatureRegistry::ValidateHeaderL( RFileReadStream &aStream, 
       
   817     TUint32& aCount, TUint32& aCountDSRs )
       
   818     {
       
   819     FUNC_LOG
       
   820 
       
   821     TUint32 identifier = aStream.ReadUint32L();
       
   822     TUint16 fileVersion = aStream.ReadUint16L();
       
   823     TUint16 fileFlags = aStream.ReadUint16L();
       
   824     aCount = aStream.ReadUint32L();
       
   825     aCountDSRs = aStream.ReadUint32L();
       
   826         
       
   827     // Carry out simple verification of file content
       
   828     if((identifier != KFileType) || fileVersion != KFileVersion || 
       
   829         fileFlags != KFileFlags )
       
   830         {
       
   831         User::Leave( KErrCorrupt );
       
   832         }
       
   833     }
       
   834 
       
   835 // -----------------------------------------------------------------------------
       
   836 // CFeatMgrFeatureRegistry::UpdateRuntimeFeaturesFileL
       
   837 // -----------------------------------------------------------------------------
       
   838 //  
       
   839 void CFeatMgrFeatureRegistry::UpdateRuntimeFeaturesFileL( TFeatureServerEntry& aFeature,
       
   840 		TFeatureChangeType aType )
       
   841     {
       
   842     FUNC_LOG
       
   843 
       
   844     // Opens a file containing a stream and prepares the stream for writing.
       
   845     TInt err( KErrNone );
       
   846     RFileWriteStream writeStream;
       
   847     TFileName path( KCFeatMgrPrivatePath );
       
   848     path[0] = iFs.GetSystemDriveChar();
       
   849     path.Append( KCRuntimeFeaturesFileName );
       
   850 
       
   851     err = writeStream.Open( iFs, path, EFileWrite  ); 
       
   852     CleanupClosePushL( writeStream );
       
   853     
       
   854     if( err == KErrPathNotFound || err == KErrNotFound )
       
   855     	{
       
   856         // Create folder and file.
       
   857     	if ( err == KErrPathNotFound )
       
   858     		{
       
   859     		path = KCFeatMgrPrivatePath;
       
   860     		path[0] = iFs.GetSystemDriveChar();
       
   861 		    User::LeaveIfError( iFs.MkDirAll( path ) );
       
   862             path.Append( KCRuntimeFeaturesFileName );
       
   863     		}
       
   864         User::LeaveIfError( writeStream.Create( iFs, path, EFileWrite ) );
       
   865         
       
   866         // Write header and entry
       
   867         RFeatureServerArray temp(1);
       
   868         CleanupClosePushL( temp );
       
   869         temp.Append( aFeature );
       
   870         WriteHeaderAndEntriesL( writeStream, temp );
       
   871         CleanupStack::PopAndDestroy( &temp );
       
   872         CleanupStack::PopAndDestroy( &writeStream );
       
   873         }
       
   874     else if( err == KErrNone )
       
   875 	    {
       
   876 	    // Close write- and open readstream
       
   877 	    CleanupStack::PopAndDestroy( &writeStream );
       
   878         RFileReadStream readStream;
       
   879         User::LeaveIfError( readStream.Open( iFs, path, EFileRead ) );
       
   880         CleanupClosePushL( readStream );
       
   881 
       
   882         // Read entries from file to temporary array
       
   883         TUint32 count;
       
   884         TUint32 countDSRs;
       
   885         ValidateHeaderL( readStream, count, countDSRs );
       
   886         TUint32 granularity = 8;
       
   887         if (count>granularity) 
       
   888         	{
       
   889         	granularity=count;
       
   890         	}
       
   891         RFeatureServerArray temp(granularity);
       
   892         CleanupClosePushL( temp );
       
   893         for(TInt i = 0; i < count; i++)
       
   894             {
       
   895             TFeatureServerEntry entry;
       
   896             entry.InternalizeL( readStream );
       
   897             temp.AppendL( entry );
       
   898             }
       
   899         // Close read-stream and handle temp array in cleanup stack
       
   900         CleanupStack::Pop( &temp );
       
   901         CleanupStack::PopAndDestroy( &readStream );
       
   902         CleanupClosePushL( temp );
       
   903 
       
   904         // Set or insert a new entry in to the array
       
   905         const TUid& uid( aFeature.FeatureUid() );
       
   906         TInt index = temp.FindInOrder( uid, FindByUid );
       
   907         if( index != KErrNotFound )
       
   908             {         
       
   909             if ( aType != EFeatureFeatureDeleted )
       
   910             	{
       
   911             	temp[index].Set( aFeature);
       
   912             	}
       
   913             else
       
   914             	{
       
   915             	temp.Remove( index );
       
   916             	}
       
   917             }
       
   918         else
       
   919             {
       
   920             User::LeaveIfError( temp.InsertInOrder( aFeature, FindByUid ) );
       
   921             }
       
   922 		
       
   923 		//Create a Temporary File
       
   924 		RFileWriteStream writeStreamTemp;
       
   925 		const TPtrC KTestFile=_L("TFEATURES.DAT");
       
   926         TFileName tempPath( KCFeatMgrPrivatePath );
       
   927 	    tempPath[0] = iFs.GetSystemDriveChar();
       
   928     	tempPath.Append( KTestFile );
       
   929     	User::LeaveIfError(writeStreamTemp.Replace( iFs,  tempPath, EFileWrite ));
       
   930     	CleanupClosePushL( writeStreamTemp);
       
   931     	WriteHeaderAndEntriesL( writeStreamTemp, temp );
       
   932     	writeStreamTemp.CommitL();
       
   933     	CleanupStack::PopAndDestroy(&writeStreamTemp);
       
   934         CleanupStack::PopAndDestroy( &temp );
       
   935         User::LeaveIfError(iFs.Replace(tempPath,path));		
       
   936        
       
   937 	    }
       
   938     else
       
   939         {
       
   940         ERROR_LOG1( "CFeatMgrFeatureRegistry::UpdateRuntimeFeatures - err %d", err );
       
   941         User::Leave( err );
       
   942         }
       
   943     }
       
   944 
       
   945 // -----------------------------------------------------------------------------
       
   946 // CFeatMgrFeatureRegistry::WriteHeaderAndEntriesL
       
   947 // -----------------------------------------------------------------------------
       
   948 //  
       
   949 void CFeatMgrFeatureRegistry::WriteHeaderAndEntriesL( RFileWriteStream &aStream, 
       
   950     RFeatureServerArray& aArray )
       
   951     {
       
   952     FUNC_LOG
       
   953 
       
   954     TInt count( aArray.Count() );
       
   955     aStream.WriteUint32L( KFileType );
       
   956     aStream.WriteUint16L( KFileVersion );
       
   957     aStream.WriteUint16L( KFileFlags );
       
   958     aStream.WriteUint32L( count );
       
   959     aStream.WriteUint32L( 0 );
       
   960     for(TInt i = 0; i < count; i++)
       
   961         {
       
   962         aArray[i].ExternalizeL( aStream );
       
   963         }
       
   964     }
       
   965 
       
   966 // -----------------------------------------------------------------------------
       
   967 // CFeatMgrFeatureRegistry::MergePluginFeatures
       
   968 // -----------------------------------------------------------------------------
       
   969 //  
       
   970 void CFeatMgrFeatureRegistry::MergePluginFeatures( 
       
   971         RArray<FeatureInfoCommand::TFeature>& aList )
       
   972     {
       
   973     FUNC_LOG
       
   974     
       
   975     TInt count = aList.Count();
       
   976 
       
   977     for ( TInt i = 0; i < count; i++ )
       
   978         {
       
   979         const TUid uid( TUid::Uid( aList[i].iFeatureID ) );
       
   980         TInt index = SearchFeature( uid );
       
   981         
       
   982         if(index != KErrNotFound)
       
   983             {
       
   984             if ( !IsFlagSet( index, EFeatureBlackListed ) )
       
   985                 {
       
   986                 // Update support-status bit
       
   987                 TBitFlags32 flags( iFeatureList[index].FeatureFlags() );
       
   988                 flags.Assign( EFeatureSupported, aList[i].iValue);
       
   989                 
       
   990                 // Set existing entry in array
       
   991                 TFeatureServerEntry entry( uid, flags, iFeatureList[index].FeatureData());
       
   992                 iFeatureList[index].Set(entry);
       
   993                 }
       
   994             else
       
   995                 {
       
   996                 INFO_LOG1( "CFeatMgrFeatureRegistry::MergePluginFeatures - 0x%08x blacklisted",
       
   997                     iFeatureList[i].FeatureUid().iUid );
       
   998                 }
       
   999             }
       
  1000         else
       
  1001             {
       
  1002             TBitFlags32 flags;
       
  1003             flags.Assign( EFeatureSupported, aList[i].iValue);
       
  1004             // Insert new entry in array
       
  1005             TFeatureServerEntry newFeature( uid, flags, KDefaultData );
       
  1006             TInt err = iFeatureList.InsertInOrder( newFeature, FindByUid );
       
  1007             INFO_LOG2( "CFeatMgrFeatureRegistry::MergePluginFeatures - 0x%08x insert result %d",
       
  1008                 newFeature.FeatureUid().iUid, err );
       
  1009             }
       
  1010         }
       
  1011     }
       
  1012     
       
  1013 // -----------------------------------------------------------------------------
       
  1014 // CFeatMgrFeatureRegistry::MergePluginFeatures
       
  1015 // -----------------------------------------------------------------------------
       
  1016 //  
       
  1017 void CFeatMgrFeatureRegistry::MergePluginFeatures( RFeatureArray& aList )
       
  1018     {
       
  1019     FUNC_LOG
       
  1020     
       
  1021     TInt count = aList.Count();
       
  1022 
       
  1023     for ( TInt i = 0; i < count; i++ )
       
  1024         {
       
  1025         //Check for feature flag errors
       
  1026         ValidateFeatureFlag(aList[i].FeatureFlags()) ; 
       
  1027         const TUid uid( aList[i].FeatureUid() );
       
  1028         TInt index = SearchFeature( uid );
       
  1029         
       
  1030         if( index != KErrNotFound )
       
  1031             {
       
  1032             if ( !IsFlagSet( index, EFeatureBlackListed ) )
       
  1033                 {
       
  1034                 // Set existing entry in array with new info and data
       
  1035                 TFeatureServerEntry entry( uid, aList[i].FeatureFlags(), aList[i].FeatureData() );
       
  1036                 iFeatureList[index].Set(entry);
       
  1037                 }
       
  1038             else
       
  1039                 {
       
  1040                 INFO_LOG1( "CFeatMgrFeatureRegistry::MergePluginFeatures - 0x%08x blacklisted",
       
  1041                     iFeatureList[i].FeatureUid().iUid );
       
  1042                 }
       
  1043             }
       
  1044         else
       
  1045             {
       
  1046             // Insert new entry in array
       
  1047             TFeatureServerEntry newFeature( uid, aList[i].FeatureFlags(), aList[i].FeatureData() );
       
  1048             TInt err = iFeatureList.InsertInOrder( newFeature, FindByUid );
       
  1049             INFO_LOG2( "CFeatMgrFeatureRegistry::MergePluginFeatures - 0x%08x insert result %d",
       
  1050                 newFeature.FeatureUid().iUid, err );
       
  1051             }
       
  1052         }
       
  1053     }
       
  1054 
       
  1055 // -----------------------------------------------------------------------------
       
  1056 // CFeatMgrFeatureRegistry::ValidateFeatureFlag
       
  1057 // Following are the rule to check err in the ROM defined feature flags
       
  1058 // Rule 1) If a feature flag is blacklisted then setting any of modifiable, persisted, Un-initialised bit will be an error
       
  1059 // Rule 2) If a feature flag is non blacklisted, non modifiable  setting any of Un-initialised, Persisted bit will be an error
       
  1060 // -----------------------------------------------------------------------------
       
  1061 //  
       
  1062    
       
  1063 TInt CFeatMgrFeatureRegistry::ValidateFeatureFlag(TBitFlags32 aFlags)
       
  1064 	{
       
  1065 	_LIT( KPanicCategory, "FEATMGR-FLAGS" );
       
  1066 
       
  1067 	
       
  1068 	if(!aFlags.IsSet(EFeatureRuntime)) //ROM defined feature flag error check
       
  1069 		{
       
  1070 		//Rule 1
       
  1071 		if(aFlags.IsSet(EFeatureBlackListed) )
       
  1072 	    	{
       
  1073 	    	 if(aFlags.IsSet(EFeatureModifiable) || aFlags.IsSet(EFeaturePersisted) || aFlags.IsSet(EFeatureUninitialized) )
       
  1074 	    	 	{
       
  1075 	    	 	//error 
       
  1076 	    	 	__ASSERT_ALWAYS(EFalse, User::Panic( KPanicCategory, EFmpInvalidFeatureBitFlagsRule1));
       
  1077                 return KErrArgument;
       
  1078 	    	  	}
       
  1079 	    	}
       
  1080 	    	
       
  1081 	    //Rule 2    	
       
  1082 	    if (!aFlags.IsSet(EFeatureModifiable))
       
  1083 	       	{
       
  1084 	       	if (aFlags.IsSet(EFeaturePersisted) || aFlags.IsSet(EFeatureUninitialized) )
       
  1085 	       	 	{
       
  1086 	        	//error 
       
  1087 	        	__ASSERT_ALWAYS(EFalse, User::Panic( KPanicCategory, EFmpInvalidFeatureBitFlagsRule2));
       
  1088                 return KErrArgument;
       
  1089 	        	}	
       
  1090 	        }
       
  1091 		}
       
  1092 	else // Runtime feature this should not be in the rom
       
  1093 		{		
       
  1094 		__ASSERT_ALWAYS(EFalse, User::Panic( KPanicCategory, EPanicInvalidFeatureInfo));
       
  1095 		return KErrArgument;
       
  1096 		}
       
  1097 	return KErrNone;
       
  1098 	}
       
  1099 
       
  1100 /**
       
  1101  * This function is used to validate feature flags that are read from the features file on the ffs.
       
  1102  * This function is also used to validate feature flags that are modified or added with the execption of MergePluginFeatures.
       
  1103  * This validation compares the flags against a set of rules. This ffs file needs to be validate separately from the 
       
  1104  * rom file. If the rom validation method is used a panic can occur which is appropriate for checking the rom but not
       
  1105  * for the ffs.  
       
  1106  * This does not validate the dsr ranges. 
       
  1107  * The following are the rules to check for errors in the run time defined feature flags
       
  1108  * Rule 1)Blacklisting of a run-time defined feature flag is an error 
       
  1109  * Rule 2)Un-initialised feature flag should be modifiable.   
       
  1110  * Funtion returns KErrArgument if a rule is broken otherwise KErrNone
       
  1111  */
       
  1112 TInt CFeatMgrFeatureRegistry::ValidateRuntimeFeatureFlagL(TBitFlags32 aFlags)
       
  1113 	{
       
  1114 	
       
  1115 	//Rule 1 (Blacklisting of run-time defined feature aFlags is not allowed)
       
  1116 	if(aFlags.IsSet(EFeatureBlackListed) ) 
       
  1117     	{
       
  1118 		//error 
       
  1119     	User::Leave( KErrArgument );
       
  1120     	}
       
  1121     	
       
  1122     //Rule 2 (non modifiable run-time feature aFlags should initialised
       
  1123 	if(!aFlags.IsSet(EFeatureModifiable) && aFlags.IsSet(EFeatureUninitialized) )
       
  1124 	 	{
       
  1125 	 	//error 
       
  1126 	 	User::Leave( KErrArgument );
       
  1127 	 	}
       
  1128 	
       
  1129 	return KErrNone;	
       
  1130 	}
       
  1131 
       
  1132 
       
  1133 /**
       
  1134  * After restore, some features might have changed. This function will examine
       
  1135  * the differences between the old feature set and the newly restored feature set
       
  1136  * to discover if any changes have taken place: then it will handle the required
       
  1137  * notifications for new, deleted and changed featuers.
       
  1138  */
       
  1139 TInt CFeatMgrFeatureRegistry::HandleRestoredFeatureNotificationsL( void )
       
  1140 	{
       
  1141 	// All comparisons are between the new list iFeatureList and the old list iFeatureListBackup
       
  1142 	TInt new_count = iFeatureList.Count();
       
  1143 	TInt old_count = iFeatureListBackup.Count();
       
  1144 	
       
  1145 	// Three lists, defining the differences between the two arrays
       
  1146 	RArray<TFeatureServerEntry> added;
       
  1147 	RArray<TFeatureServerEntry> removed;
       
  1148 	RArray<TFeatureServerEntry> changed;
       
  1149 
       
  1150 	// Regarding the newer iFeatureList array
       
  1151 	// Get the features according to the "new" iFeatureList array
       
  1152 	for( TInt i=0; i < new_count; i++ )
       
  1153 		{
       
  1154 	    // If not set, the feature flag is a ROM or plug-in
       
  1155 	    if( iFeatureList[i].FeatureFlags().IsSet(EFeatureRuntime) )
       
  1156 	        {
       
  1157 	        TUid uid( iFeatureList[i].FeatureUid() );
       
  1158 		    TInt index = iFeatureListBackup.FindInOrder( uid, FindByUid );
       
  1159 		    
       
  1160 			// KErrNotFound, if no matching object can be found
       
  1161 			if( KErrNotFound == index )
       
  1162 				{
       
  1163 				// Recently added feature
       
  1164 				added.Append( iFeatureList[i] );
       
  1165 				}
       
  1166 			else
       
  1167 				{
       
  1168 				// Get the features in iFeatureList that have recently been altered
       
  1169 		        TFeatureServerEntry old_item = iFeatureListBackup[index];
       
  1170 		        TFeatureServerEntry new_item = iFeatureList[i];
       
  1171 		        TUint32 old_flags = old_item.FeatureFlags().Value();
       
  1172 		        TUint32 new_flags = new_item.FeatureFlags().Value();
       
  1173 		        unsigned long int old_data = old_item.FeatureData();
       
  1174 		        unsigned long int new_data = new_item.FeatureData();
       
  1175 	        	// if any thing has changed, then add it to our list.
       
  1176 		        // there is no != overload for TBitFlags32
       
  1177 				if( !( old_flags == new_flags) || !( old_data == new_data) )
       
  1178 					{
       
  1179 					// changed in the "new" iFeatureList array
       
  1180 					changed.Append( iFeatureList[i] );
       
  1181 					}
       
  1182 				}
       
  1183 		
       
  1184 	        } // end if ! EFeatureRuntime
       
  1185 		} // end loop
       
  1186 
       
  1187 
       
  1188 	// Regarding the older iFeatureListBackup array
       
  1189 	// Get the features according to the "old" iFeatureListBackup array
       
  1190 	for( TInt i=0; i < old_count; i++ )
       
  1191 		{
       
  1192 	    // If not set, the feature flag is a ROM or plug-in
       
  1193 	    if( iFeatureListBackup[i].FeatureFlags().IsSet(EFeatureRuntime) )
       
  1194 	        {
       
  1195 	        TUid uid( iFeatureListBackup[i].FeatureUid() );
       
  1196 		    TInt index = iFeatureList.FindInOrder( uid, FindByUid );
       
  1197 		    
       
  1198 			// KErrNotFound, if no matching object can be found
       
  1199 			if( KErrNotFound == index )
       
  1200 				{
       
  1201 				// Recently removed feature
       
  1202 				removed.Append( iFeatureListBackup[i] );
       
  1203 				}
       
  1204 			// the else has already been completed in previous loop
       
  1205 		
       
  1206 	        } // end if ! EFeatureRuntime
       
  1207 		} // end loop
       
  1208 	
       
  1209 	TInt size_added 	= added.Count();
       
  1210 	TInt size_changed 	= changed.Count();
       
  1211 	TInt size_removed 	= removed.Count();
       
  1212 
       
  1213 	// notify the added features
       
  1214     for( TInt i = 0; i < size_added; i++ )
       
  1215         {
       
  1216         TFeatureServerEntry entry( added[i].FeatureUid(), added[i].FeatureFlags(), added[i].FeatureData() );
       
  1217         TFeatureChangeType changeType( EFeatureFeatureCreated );
       
  1218         iObserver.HandleFeatureChange( entry, changeType );
       
  1219         }
       
  1220 
       
  1221 	// notify the changed features
       
  1222     for( TInt i = 0; i < size_changed; i++ )
       
  1223         {
       
  1224         TFeatureServerEntry entry( changed[i].FeatureUid(), changed[i].FeatureFlags(), changed[i].FeatureData() );
       
  1225         TFeatureChangeType changeType( EFeatureStatusUpdated );
       
  1226         iObserver.HandleFeatureChange( entry, changeType );        
       
  1227         }
       
  1228 
       
  1229 	// notify the delete features
       
  1230     for( TInt i = 0; i < size_removed; i++ )
       
  1231         {
       
  1232         TFeatureServerEntry entry( removed[i].FeatureUid(), removed[i].FeatureFlags(), removed[i].FeatureData() );
       
  1233         TFeatureChangeType changeType( EFeatureFeatureDeleted );
       
  1234         iObserver.HandleFeatureChange( entry, changeType );
       
  1235         }
       
  1236 	
       
  1237 	return( 0 );
       
  1238 	}
       
  1239 
       
  1240 // -----------------------------------------------------------------------------
       
  1241 // CFeatMgrFeatureRegistry::SWIStart
       
  1242 // -----------------------------------------------------------------------------
       
  1243 //
       
  1244 TInt CFeatMgrFeatureRegistry::SWIStart(TUint aSWIProcessId)
       
  1245 	{
       
  1246 	FUNC_LOG
       
  1247 	
       
  1248 	// If a previous call to SWIStart was made then return an error indicating that SWI
       
  1249 	// is already running. This assures that no two exes will enable the caching
       
  1250 	// mechanism at the same time.
       
  1251 	if( iSWICacheFeature )
       
  1252 		{
       
  1253 		INFO_LOG( "CFeatMgrFeatureRegistry::SWIStart - Already in use");
       
  1254 		return KErrInUse;
       
  1255 		}
       
  1256 	
       
  1257 	RProperty propertyHndl;
       
  1258 	TInt err =propertyHndl.Attach(KUidSystemCategory, KSAUidSoftwareInstallKeyValue);
       
  1259 	if (KErrNone != err)
       
  1260 		{
       
  1261 		return err;
       
  1262 		}
       
  1263 	TInt val = -1;
       
  1264 	err = propertyHndl.Get(val);
       
  1265 	propertyHndl.Close();
       
  1266 
       
  1267 	if( KErrNone == err )
       
  1268 		{
       
  1269 		// If an installation/uninstallation has started and no finishing status has been set for it
       
  1270 		if( ((val&ESASwisInstall) || (val&ESASwisUninstall)) && !(val&ESASwisStatusNone) )
       
  1271 			{
       
  1272 			// Set a flag to tell FeatMgr that features modified from this point onwards
       
  1273 		    // until a call to SWIEnd must be cached.
       
  1274 		    iSWICacheFeature = ETrue;
       
  1275 		    // SWI installation/uninstallation is in progress
       
  1276 		    iSWIStatus = ESWIInstalling;
       
  1277 		    // Set the ID of the process issuing Feature Manager commands to be cached
       
  1278 			iSWIProcessId = aSWIProcessId;
       
  1279 			// Start listening to P&S install property
       
  1280 		    TRAP(err, iSWIListener = CSWIListener::NewL(this));
       
  1281 		    if (KErrNone != err)
       
  1282 		    	{
       
  1283 		    	return err;
       
  1284 		    	}
       
  1285 		    
       
  1286 		    // Start the timer to handle the case of the launched exe hanging or not calling SWIEnd
       
  1287 		    // after SWIStart
       
  1288 		    TRAP(err, iSWITimer = CSWITimer::NewL(TTimeIntervalMicroSeconds32(SWITIMEOUT), this));
       
  1289 		    if (KErrNone != err)
       
  1290 		    	{
       
  1291 		    	return err;
       
  1292 		    	}
       
  1293 		    	
       
  1294 		    INFO_LOG( "CFeatMgrFeatureRegistry::SWIStart - err KErrNone");
       
  1295 		    return KErrNone;
       
  1296 			}
       
  1297 		}
       
  1298 	INFO_LOG( "CFeatMgrFeatureRegistry::SWIStart - err KErrNotReady");
       
  1299 
       
  1300 	return KErrNotReady;
       
  1301 	}
       
  1302 
       
  1303 // -----------------------------------------------------------------------------
       
  1304 // CFeatMgrFeatureRegistry::SWIEnd
       
  1305 // -----------------------------------------------------------------------------
       
  1306 //
       
  1307 TInt CFeatMgrFeatureRegistry::SWIEnd(TUint aSWIProcessId)
       
  1308 	{
       
  1309 	FUNC_LOG
       
  1310 
       
  1311 	// reset the number of operations cached
       
  1312 	iSWIOperations = 0;
       
  1313 	
       
  1314 	// If it is the same process that made a call to SWIStart and caching is in progress
       
  1315 	if( iSWIProcessId == aSWIProcessId && iSWICacheFeature )
       
  1316 		{
       
  1317 		if( iSWIStatus == ESWIAborted )
       
  1318 			{
       
  1319 			SWIReset();
       
  1320 			
       
  1321 			INFO_LOG( "CFeatMgrFeatureRegistry::SWIEnd - SWIStatus = ESWIAborted");
       
  1322 			return KErrNone;
       
  1323 			}
       
  1324 		else if( iSWIStatus == ESWIInstalling )
       
  1325 			{
       
  1326 			// Stop time-out
       
  1327 			if( iSWITimer )
       
  1328 				{
       
  1329 				delete iSWITimer;
       
  1330 				iSWITimer = NULL;
       
  1331 				}
       
  1332 			// Stop caching
       
  1333 			iSWICacheFeature = EFalse;			
       
  1334 			
       
  1335 			TInt err = KErrGeneral;
       
  1336 
       
  1337 			if( !iOomOccured )
       
  1338 				{
       
  1339 				if( iAddFeatCount>0 )
       
  1340 					{
       
  1341 					err = iFeatureList.Reserve(iFeatureList.Count() + iAddFeatCount);
       
  1342                     if (err == KErrNoMemory)
       
  1343                          {
       
  1344                          iSWIStatus = ESWIOutOfMemory;
       
  1345                          }
       
  1346 					}
       
  1347 				}
       
  1348 			else
       
  1349 				{
       
  1350 				err = KErrNoMemory;
       
  1351 				iSWIStatus = ESWIOutOfMemory;
       
  1352 				}
       
  1353 			
       
  1354 			INFO_LOG( "CFeatMgrFeatureRegistry::SWIEnd - SWIStatus = ESWIInstalling");
       
  1355 			return err;
       
  1356 			}
       
  1357 		}
       
  1358 
       
  1359 	INFO_LOG( "CFeatMgrFeatureRegistry::SWIEnd - err KErrNotReady");
       
  1360 	return KErrNotReady;
       
  1361 	}
       
  1362 
       
  1363 // -----------------------------------------------------------------------------
       
  1364 // CFeatMgrFeatureRegistry::SWICacheCommand
       
  1365 // -----------------------------------------------------------------------------
       
  1366 //
       
  1367 TInt CFeatMgrFeatureRegistry::SWICacheCommand(TSWIOperationCat aOptCat, TFeatureServerEntry aFeature)
       
  1368 	{
       
  1369 	FUNC_LOG
       
  1370 	
       
  1371 	TInt err;
       
  1372 
       
  1373 	if (iSWIOperations >= MAXSWIOPS)
       
  1374 		{
       
  1375 		err = KErrArgument;
       
  1376 		}
       
  1377 	else if (iOomOccured)
       
  1378 		{
       
  1379 		err = KErrNoMemory;
       
  1380 		}
       
  1381 	else
       
  1382 		{
       
  1383 		if( aOptCat == ESWIAddFeat )
       
  1384 			{
       
  1385 			++iAddFeatCount;
       
  1386 			}		
       
  1387 		TSWICachedOperation operation;
       
  1388 		operation.iFeatEntry = aFeature;
       
  1389 		operation.iCat = aOptCat;
       
  1390     	err = iSWICachedOperations.Append(operation);
       
  1391     	if( err == KErrNoMemory)
       
  1392     		{
       
  1393     		iOomOccured = ETrue;
       
  1394     		}
       
  1395     	else if( err == KErrNone )
       
  1396     		{
       
  1397     		++iSWIOperations;
       
  1398     		}
       
  1399 		}
       
  1400 	return err;
       
  1401 	}
       
  1402 
       
  1403 // -----------------------------------------------------------------------------
       
  1404 // CFeatMgrFeatureRegistry::CommitSWIFeatChanges
       
  1405 // -----------------------------------------------------------------------------
       
  1406 //
       
  1407 void CFeatMgrFeatureRegistry::CommitSWIFeatChanges()
       
  1408 	{
       
  1409 	FUNC_LOG
       
  1410 	
       
  1411 	// Commit all cached features.
       
  1412 	if( !iSWICacheFeature )
       
  1413 		{
       
  1414 		TInt count = iSWICachedOperations.Count();
       
  1415 
       
  1416 		for( TInt i=0; i<count; ++i )
       
  1417 			{
       
  1418 			TSWIOperationCat optCat = iSWICachedOperations[i].iCat;
       
  1419 	
       
  1420 			switch(optCat)
       
  1421 				{
       
  1422 			case ESWIAddFeat:
       
  1423 				{
       
  1424 				AddFeature( iSWICachedOperations[i].iFeatEntry, 0 );
       
  1425 				}
       
  1426 				break;
       
  1427 			case ESWIDeleteFeat:
       
  1428 				{
       
  1429 				DeleteFeature( iSWICachedOperations[i].iFeatEntry.FeatureUid() );
       
  1430 				}
       
  1431 				break;
       
  1432 			case ESWISetFeatAndData:
       
  1433 				{
       
  1434 				TUint32 data = iSWICachedOperations[i].iFeatEntry.FeatureData();				
       
  1435 				SetFeature( iSWICachedOperations[i].iFeatEntry.FeatureUid(),
       
  1436 							iSWICachedOperations[i].iFeatEntry.FeatureFlags().Value(),
       
  1437 							&data);
       
  1438 		    	}
       
  1439 				break;
       
  1440 			case ESWISetFeatData:
       
  1441 				{
       
  1442 				TUint32 data = iSWICachedOperations[i].iFeatEntry.FeatureData();
       
  1443 				SetFeature(iSWICachedOperations[i].iFeatEntry.FeatureUid(),
       
  1444 							EFeatureSupportUntouch,&data);
       
  1445 				}
       
  1446 				break;
       
  1447 			default:
       
  1448 				break;
       
  1449 				};
       
  1450 			}
       
  1451 		
       
  1452 		INFO_LOG( "CFeatMgrFeatureRegistry::CommitSWIFeatChanges - Committing completed");
       
  1453 		}
       
  1454 	SWIReset();
       
  1455 	}
       
  1456 
       
  1457 // -----------------------------------------------------------------------------
       
  1458 // CFeatMgrFeatureRegistry::SWIReset
       
  1459 // -----------------------------------------------------------------------------
       
  1460 //
       
  1461 void CFeatMgrFeatureRegistry::SWIReset()
       
  1462 	{
       
  1463 	// Clear cached-features array
       
  1464 	iSWICachedOperations.Close();
       
  1465 
       
  1466 	// Reset caching flag
       
  1467 	iSWICacheFeature = EFalse;
       
  1468 	
       
  1469 	// Reset SWI process Id
       
  1470 	iSWIProcessId = 1;
       
  1471 	
       
  1472 	// Reset SWI completion status
       
  1473 	iSWIStatus = ESWIComplete;
       
  1474 
       
  1475 	// Reset the check for "out of memory" condition
       
  1476 	iOomOccured = EFalse;
       
  1477 	
       
  1478 	// Reset the operations counter
       
  1479 	iSWIOperations = 0;
       
  1480 	
       
  1481 	// No need to listen to P&S insall property any more
       
  1482 	delete iSWIListener;
       
  1483 	iSWIListener = NULL;
       
  1484 	
       
  1485 	// Stop time-out
       
  1486 	if( iSWITimer )
       
  1487 		{
       
  1488 		delete iSWITimer;
       
  1489 		iSWITimer = NULL;
       
  1490 		}
       
  1491 	}
       
  1492 
       
  1493 // -----------------------------------------------------------------------------
       
  1494 // CFeatMgrFeatureRegistry::SWIAborted
       
  1495 // -----------------------------------------------------------------------------
       
  1496 //
       
  1497 void CFeatMgrFeatureRegistry::SWIAborted()
       
  1498 	{
       
  1499 	FUNC_LOG
       
  1500 	
       
  1501 	// If abort occured before SWIEnd is called
       
  1502 	if( iSWICacheFeature )
       
  1503 		{
       
  1504 		INFO_LOG( "CFeatMgrFeatureRegistry::SWIAborted - Abort occured before SWIEnd was called");
       
  1505 		iSWIStatus = ESWIAborted;
       
  1506 		}
       
  1507 	else
       
  1508 		{
       
  1509 		INFO_LOG( "CFeatMgrFeatureRegistry::SWIAborted - Abort occured after SWIEnd was called");
       
  1510 		SWIReset();
       
  1511 		}
       
  1512 	}
       
  1513 
       
  1514 // -----------------------------------------------------------------------------
       
  1515 // CFeatMgrFeatureRegistry::SWITimedOut
       
  1516 // -----------------------------------------------------------------------------
       
  1517 //
       
  1518 void CFeatMgrFeatureRegistry::SWITimedOut()
       
  1519 	{
       
  1520 	FUNC_LOG
       
  1521 	
       
  1522 	if( iSWICacheFeature )
       
  1523 		{
       
  1524 		INFO_LOG( "CFeatMgrFeatureRegistry::SWITimedOut - Timeout expired");
       
  1525 		SWIReset();
       
  1526 		}
       
  1527 	}
       
  1528 
       
  1529 // -----------------------------------------------------------------------------
       
  1530 // CFeatMgrFeatureRegistry::SWICacheStarted
       
  1531 // -----------------------------------------------------------------------------
       
  1532 //
       
  1533 TBool CFeatMgrFeatureRegistry::SWICacheStarted()
       
  1534 	{
       
  1535 	return iSWICacheFeature;
       
  1536 	}
       
  1537 
       
  1538 // -----------------------------------------------------------------------------
       
  1539 // CFeatMgrFeatureRegistry::SWICacheStatus
       
  1540 // -----------------------------------------------------------------------------
       
  1541 //
       
  1542 TBool CFeatMgrFeatureRegistry::SWICacheStatusOOM()
       
  1543 	{
       
  1544 	if( iSWIStatus == ESWIOutOfMemory )
       
  1545 		{
       
  1546 		return ETrue;
       
  1547 		}
       
  1548 	return EFalse;
       
  1549 	}
       
  1550 	
       
  1551 //  End of File