os/persistentdata/featuremgmt/featuremgr/src/serverexe/featmgrsession.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-2010 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 "featmgrsession.h"
    21 #include "featmgrfeatureentry.h"
    22 #include "featmgrdebug.h"
    23 
    24 // CONSTANTS
    25 const TInt CFeatMgrPendingRequest::iOffset = _FOFF( CFeatMgrPendingRequest,iLink );
    26 
    27 // LOCAL CONSTANTS AND MACROS
    28 _LIT( KPanicCategory, "FeatMgrSession" );
    29 
    30 // ============================= LOCAL FUNCTIONS ===============================
    31 
    32 // ============================ MEMBER FUNCTIONS ===============================
    33 
    34 // -----------------------------------------------------------------------------
    35 // CFeatMgrSession::CFeatMgrSession
    36 // C++ constructor
    37 // -----------------------------------------------------------------------------
    38 //
    39 CFeatMgrSession::CFeatMgrSession( CFeatMgrServer& aServer, CFeatMgrFeatureRegistry& aRegistry )
    40     : iFeatMgrServer( aServer ),
    41     iRegistry( aRegistry ),
    42     iList( CFeatMgrPendingRequest::iOffset )
    43     {
    44     }
    45 
    46 // -----------------------------------------------------------------------------
    47 // CFeatMgrSession::NewL
    48 // Two-phased constructor.
    49 // -----------------------------------------------------------------------------
    50 //
    51 CFeatMgrSession* CFeatMgrSession::NewL( CFeatMgrServer& aServer, 
    52     CFeatMgrFeatureRegistry& aRegistry )
    53     {
    54     FUNC_LOG
    55 
    56     CFeatMgrSession* self = new( ELeave ) CFeatMgrSession( aServer, aRegistry );
    57     
    58     return self;
    59     }
    60 
    61 #ifdef EXTENDED_FEATURE_MANAGER_TEST
    62 void CFeatMgrSession::CreateL()
    63     {
    64     iFeatMgrServer.AddSession();
    65     }
    66 #endif
    67 
    68 // ---------------------------------------------------------
    69 // Destructor
    70 // ---------------------------------------------------------
    71 //
    72 CFeatMgrSession::~CFeatMgrSession()
    73     {
    74     FUNC_LOG
    75 
    76     iNotifyFeatures.Close();
    77 
    78     while ( !iList.IsEmpty() )
    79         {
    80         CFeatMgrPendingRequest* pendingReq = iList.First();  
    81         iList.Remove( *pendingReq );
    82         delete pendingReq;
    83         }
    84     
    85     iList.Reset();
    86 #ifdef EXTENDED_FEATURE_MANAGER_TEST
    87     iFeatMgrServer.DropSession();
    88 #endif
    89     }
    90 
    91 // -----------------------------------------------------------------------------
    92 // CFeatMgrSession::PanicClient
    93 // RMessage2::Panic() also completes the message. This is:
    94 // (a) important for efficient cleanup within the kernel
    95 // (b) a problem if the message is completed a second time
    96 // -----------------------------------------------------------------------------
    97 //
    98 void CFeatMgrSession::PanicClient( const RMessage2& aMessage, TFeatMgrPanic aPanic )
    99     {
   100     INFO_LOG1( "CFeatMgrSession::PanicClient(aPanic 0x%x)", aPanic);
   101 
   102 	aMessage.Panic( KPanicCategory, aPanic );
   103     }
   104 
   105 TBool CFeatMgrSession::IsWriteOperation( const TInt aFunction ) const
   106     {
   107         switch ( aFunction )
   108             {
   109             case EFeatMgrEnableFeature:
   110             case EFeatMgrDisableFeature:
   111             case EFeatMgrAddFeature:
   112             case EFeatMgrSetFeatureAndData:
   113             case EFeatMgrSetFeatureData:
   114             case EFeatMgrDeleteFeature:
   115             case EFeatMgrSWIStart:
   116             case EFeatMgrSWIEnd:
   117                 return ETrue;
   118             default:
   119                 return EFalse;
   120             }
   121     }
   122 
   123 // -----------------------------------------------------------------------------
   124 // CFeatMgrSession::ServiceL
   125 // Calls request handling functions. Also traps any leaves and signals client if
   126 // error occurs.
   127 // -----------------------------------------------------------------------------
   128 //
   129 void CFeatMgrSession::ServiceL( const RMessage2& aMessage )
   130     {
   131     FUNC_LOG
   132     // If plugins are not ready all request will be queued. 
   133     // During backup & restore operation, all write request 
   134     //  e.g. EnableFeature will return with KErrServerBusy
   135     TInt msgCmd = aMessage.Function();
   136     if ( !iFeatMgrServer.PluginsReady() || ( iFeatMgrServer.BURIsInProgress()  && IsWriteOperation( msgCmd ) ) )
   137         {
   138         if ( iFeatMgrServer.BURIsInProgress() )
   139             {
   140             INFO_LOG( "CFeatMgrSession::ServiceL() - backup/restore is in progress - no write operation allowed" );
   141             aMessage.Complete( KErrServerBusy );
   142             }
   143         else
   144             {
   145             INFO_LOG( "CFeatMgrSession::ServiceL() - plugins not ready" );
   146             CFeatMgrPendingRequest* request=NULL;
   147             TRAPD(error,request=CFeatMgrPendingRequest::NewL( aMessage ));
   148             if (error!=KErrNone)
   149               {
   150               LOG_IF_ERROR1( error, "CFeatMgrSession::ServiceL(): Error in Adding Pending Request: %d", error );
   151               //cannot create pending request so need to indicate to the client rather than letting the cient wait forever.
   152               aMessage.Complete(error);              
   153               }
   154             else
   155               {
   156               iList.AddLast(*request);
   157               }
   158             }
   159         }
   160     else
   161         {
   162         #if defined(FEATMGR_INFO_LOG_ENABLED)
   163             // check memory usage
   164             TInt biggestBlock;
   165             INFO_LOG1( "CFeatMgrSession::ServiceL() - #### Memory Available in Heap: %6d ####", 
   166                                     User::Heap().Available(biggestBlock) );
   167             INFO_LOG1( "CFeatMgrSession::ServiceL() - #### Biggest block:            %6d ####", 
   168                                     biggestBlock );
   169         #endif
   170 
   171         TRAPD( error, DispatchMessageL( aMessage ) );
   172 
   173         LOG_IF_ERROR1( error, "CFeatMgrSession::ServiceL(): Error in DispatchMessageL: %d", 
   174                                      error );
   175 
   176         if( aMessage.Function() != EFeatMgrReqNotify )
   177             {
   178             aMessage.Complete( error );
   179             }
   180         }
   181     }
   182     
   183 // -----------------------------------------------------------------------------
   184 // CFeatMgrSession::ServicePendingRequestsL
   185 // Calls request handling functions. Also traps any leaves and signals client if
   186 // error occurs.
   187 // -----------------------------------------------------------------------------
   188 //
   189 void CFeatMgrSession::ServicePendingRequestsL()
   190     {       
   191     FUNC_LOG
   192     
   193     while ( !iList.IsEmpty() )
   194         {
   195         CFeatMgrPendingRequest* pendingReq = iList.First();  
   196         
   197         TRAPD( error, DispatchMessageL( pendingReq->iMessage ) );
   198 
   199         LOG_IF_ERROR1( error, "CFeatMgrSession::ServicePendingRequestsL(): Error in DispatchMessageL: %d", 
   200             error );
   201 
   202         if( pendingReq->iMessage.Function() != EFeatMgrReqNotify )
   203             {
   204             pendingReq->iMessage.Complete( error );
   205             }
   206         
   207         iList.Remove( *pendingReq );
   208         delete pendingReq;
   209         }
   210     
   211     iList.Reset();
   212     }
   213 
   214 // -----------------------------------------------------------------------------
   215 // CFeatMgrSession::DispatchMessageL
   216 // Calls matching function of CFeatMgrServer for handling the request.
   217 // -----------------------------------------------------------------------------
   218 //
   219 void CFeatMgrSession::DispatchMessageL( const RMessage2& aMessage )
   220     {
   221     FUNC_LOG
   222     
   223     INFO_LOG1( "CFeatMgrSession::DispatchMessageL(0x%x)", aMessage.Function() );
   224 
   225     TInt msgCmd = aMessage.Function();
   226     
   227     // Getting the ID of the process making the calls on feature manager. This ID is used
   228     // for the addition, deletion, setting, enabling, and disabling functions.
   229     TUint processId = 0;	// default value for a process id
   230     TInt getIdErr = KErrGeneral;
   231     if( msgCmd >= EFeatMgrEnableFeature && msgCmd <= EFeatMgrSWIEnd )
   232     	{
   233 	    RThread thread;
   234 	    getIdErr = aMessage.Client(thread, EOwnerProcess);
   235 	    if( getIdErr == KErrNone)
   236 	    	{
   237 		    RProcess process;
   238 		    getIdErr = thread.Process(process);
   239 		    if( getIdErr == KErrNone)
   240 		    	{
   241 		    	TProcessId prcId = process.Id();
   242 		    	processId = TUint(prcId.Id());
   243 		    	}
   244 	    	}
   245     	}
   246 	    	
   247     // Check command code and call appropriate function
   248     switch ( msgCmd )
   249         {
   250     	case EFeatMgrFeatureSupported:
   251     	    {
   252     	    TFeatureEntry feature;
   253     	    TPckg<TFeatureEntry> pckg( feature );
   254     	    aMessage.ReadL( 0, pckg );
   255     	    TFeatureServerEntry feat( feature );
   256     	    TInt supported = iRegistry.IsFeatureSupported( feat );
   257     	    // Construct entry for passing back to client.
   258     	    TFeatureEntry featBack( feat.FeatureUid(), feat.FeatureFlags(), feat.FeatureData() );
   259     	    TPckgC<TFeatureEntry> pckgBack( featBack );
   260             TPckgC<TInt> resPckg( supported );
   261             aMessage.WriteL( 0, pckgBack );
   262             aMessage.WriteL( 1, resPckg );
   263     	    
   264     	    break;
   265     	    }
   266     	    
   267         case EFeatMgrFeaturesSupported:
   268     	    {
   269         	TInt count( aMessage.Int0() );
   270         	TInt responseCount( 0 );
   271         	RFeatureArray temp;
   272         	CleanupClosePushL( temp );
   273         	temp.ReserveL( count );
   274         	
   275             for ( TInt i = 0; i < count; i++ )
   276                 {
   277                 TFeatureEntry feature;
   278                 TPckg<TFeatureEntry> pckg( feature );
   279                 TInt offset = i * sizeof(TFeatureEntry);
   280                 // Read feature entry and fetch entry status/data
   281                 aMessage.ReadL( 1, pckg, offset );
   282                 TFeatureServerEntry feat( feature );
   283                 TInt supported = iRegistry.IsFeatureSupported( feat );
   284                 
   285                 // Non-existing and uninitialised feature entries are not returned.
   286                 if( supported != KErrNotFound && supported != KErrNotReady )
   287                     {
   288                     responseCount++;
   289                     TFeatureEntry featBack( feat.FeatureUid(), feat.FeatureFlags(), 
   290                         feat.FeatureData() );
   291                     // Can't write to same slot before reading entries first
   292                     temp.AppendL( featBack );
   293                     }
   294                 }
   295                 
   296             // Write found entries back to client
   297             for ( TInt i = 0; i < responseCount; i++ )
   298                 {
   299                 TInt offset = i * sizeof(TFeatureEntry);
   300                 TPckgC<TFeatureEntry> pckgBack( temp[i] );
   301                 aMessage.WriteL( 1, pckgBack, offset );
   302                 }
   303             CleanupStack::PopAndDestroy( &temp );
   304 
   305             // Write number of found entries back to client
   306             TPckgC<TInt> resPckg( responseCount );
   307             aMessage.WriteL( 2, resPckg );
   308     	    
   309     	    break;
   310     	    }
   311         
   312         case EFeatMgrNumberOfSupportedFeatures:
   313     	    {
   314     	    TInt count = iRegistry.NumberOfSupportedFeatures();
   315             TPckgC<TInt> resPckg( count );
   316             aMessage.WriteL( 0, resPckg );
   317     	    
   318     	    break;
   319     	    }
   320     	    
   321     	case EFeatMgrListSupportedFeatures:
   322     	    {   
   323             RFeatureUidArray supportedFeatures;
   324             CleanupClosePushL( supportedFeatures );
   325             
   326             iRegistry.SupportedFeaturesL( supportedFeatures );
   327             TInt count( supportedFeatures.Count() );
   328            
   329             if ( aMessage.Int0() == count )
   330                 {
   331                 for ( TInt i = 0; i < count; i++ )
   332                     {
   333                     TPckg<TUid> pckg( supportedFeatures[i] );
   334                     TInt offset = i * sizeof(TUid);
   335                     aMessage.WriteL( 1, pckg, offset );
   336                     }
   337                 
   338                 CleanupStack::PopAndDestroy( &supportedFeatures );
   339                 }
   340             else
   341                 {
   342                 CleanupStack::PopAndDestroy( &supportedFeatures );
   343                 User::Leave( KErrServerBusy );
   344                 }
   345          	break;
   346     	    }
   347 
   348     	case EFeatMgrEnableFeature:
   349     	    {
   350     	    if( getIdErr == KErrNone )
   351     	    	{
   352 	    	    TUid feature = TUid::Uid(aMessage.Int0());
   353 	    	    getIdErr = iRegistry.SetFeature( feature, EFeatureSupportEnable, NULL, processId );
   354     	    	}
   355     	    TPckgC<TInt> resPckg( getIdErr );
   356 	        aMessage.WriteL( 1, resPckg );
   357 
   358 	        break;
   359     	    }
   360   		
   361   		case EFeatMgrDisableFeature:
   362     	    {
   363     	    if( getIdErr == KErrNone )
   364     	    	{
   365 	    	    TUid feature = TUid::Uid(aMessage.Int0());
   366 	    	    getIdErr = iRegistry.SetFeature( feature, EFeatureSupportDisable, NULL, processId );
   367     	    	}    	    
   368             TPckgC<TInt> resPckg( getIdErr );
   369             aMessage.WriteL( 1, resPckg );
   370     	    
   371     	    break;
   372     	    }
   373 
   374         case EFeatMgrAddFeature:
   375     	    {
   376     	    if( getIdErr == KErrNone)
   377     	    	{
   378     	    	TFeatureEntry feature;
   379         	    TPckg<TFeatureEntry> pckg( feature );
   380         	    aMessage.ReadL( 0, pckg );
   381         	    TFeatureServerEntry feat( feature );
   382         	    getIdErr = iRegistry.AddFeature( feat, processId );
   383     	    	}    	    
   384             TPckgC<TInt> resPckg( getIdErr );
   385             aMessage.WriteL( 1, resPckg );
   386     	    
   387     	    break;
   388     	    }
   389         
   390         case EFeatMgrDeleteFeature:
   391     	    {
   392     	    if( getIdErr == KErrNone)
   393     	    	{
   394     	    	TUid feature = TUid::Uid(aMessage.Int0());
   395     	    	getIdErr = iRegistry.DeleteFeature( feature, processId );
   396     	    	}
   397     	    TPckgC<TInt> resPckg( getIdErr );
   398             aMessage.WriteL( 1, resPckg );
   399     	    
   400     	    break;
   401     	    }
   402         
   403         case EFeatMgrSetFeatureAndData:
   404     	    {
   405     	    if( getIdErr == KErrNone)
   406     	    	{
   407     	    	TUid feature = TUid::Uid(aMessage.Int0());
   408 	    	    TBool enable = aMessage.Int1();
   409 	    	    TUint32 data = aMessage.Int2();
   410 	    	    getIdErr = iRegistry.SetFeature( feature, enable, &data, processId );
   411     	    	}
   412     	    TPckgC<TInt> resPckg( getIdErr );
   413             aMessage.WriteL( 3, resPckg );
   414     	    
   415     	    break;
   416     	    }
   417         
   418         case EFeatMgrSetFeatureData:
   419     	    {
   420     	    if( getIdErr == KErrNone)
   421     	    	{
   422     	    	TUid feature = TUid::Uid(aMessage.Int0());
   423 	    	    TUint32 data = aMessage.Int1();
   424 	    	    getIdErr = iRegistry.SetFeature( feature, EFeatureSupportUntouch, &data, processId );
   425     	    	}
   426     	    TPckgC<TInt> resPckg( getIdErr );
   427             aMessage.WriteL( 2, resPckg );
   428     	    
   429     	    break;
   430     	    }
   431         
   432         case EFeatMgrReqNotify:
   433     	    {
   434     	    // When client requests notification for feature, it could be checked
   435     	    // whether feature exists at all and even whether feature modifiable,
   436     	    // i.e. could request ever cause notification. If this will be done, 
   437     	    // remember document error codes in API documentation.
   438     	    
   439     	    // Message is needed for later signaling of client upon feature change.
   440     	    if( iNotifyMessage.IsNull() ) 
   441     	        {
   442     	        iNotifyMessage = aMessage;
   443     	        }
   444     	    else
   445     	        {
   446     	        PanicClient( aMessage, EPanicNotifyRequest );
   447     	        }
   448     	        
   449     	    break;
   450     	    }
   451         
   452         case EFeatMgrReqNotifyUids:
   453     	    {
   454     	    // When client requests notification for features, it could be checked
   455     	    // whether features exists at all and even whether features modifiable,
   456     	    // i.e. could request ever cause notification. If this will be done, 
   457     	    // remember document error codes in API documentation.
   458     	    
   459     	    TInt err( KErrNone );
   460     	    
   461         	// Fetch transfer buffer from client
   462         	TInt count( aMessage.Int0() );
   463         	err = iNotifyFeatures.Reserve( count );
   464         	
   465         	if( err == KErrNone )
   466         	    {
   467                 for ( TInt i = 0; i < count; i++ )
   468                     {
   469                     TUid feature;
   470                     TPckg<TUid> pckg( feature );
   471                     TInt offset = i * sizeof(TUid);
   472                     aMessage.ReadL( 1, pckg, offset );
   473                     err = iNotifyFeatures.Append( feature );
   474                     if( err != KErrNone )
   475                         {
   476                         break;
   477                         }
   478                     }
   479         	    }
   480     	    
   481             TPckgC<TInt> resPckg( err );
   482             aMessage.WriteL( 2, resPckg );
   483     	    
   484     	    break;
   485     	    }
   486         
   487         case EFeatMgrReqNotifyCancel:
   488     	    {
   489     	    TUid feature = TUid::Uid(aMessage.Int0());
   490     	    TInt index( iNotifyFeatures.Find( feature ) );
   491     	    TInt err( KErrNotFound );
   492     	    
   493     	    if( index != KErrNotFound )
   494     	        {
   495     	        err = KErrNone;
   496     	        iNotifyFeatures.Remove( index );
   497     	        }
   498     	    
   499     	    // If no more features to be notified, complete request.
   500     	    if( !iNotifyFeatures.Count() 
   501     	        && iNotifyMessage.IsNull() == EFalse)
   502     	        {
   503     	        iNotifyMessage.Complete( KErrCancel );
   504     	        }
   505     	    
   506             TPckgC<TInt> resPckg( err );
   507             aMessage.WriteL( 1, resPckg );
   508     	    
   509     	    break;
   510     	    }
   511         
   512         case EFeatMgrReqNotifyCancelAll:
   513     	    {
   514     	    iNotifyFeatures.Reset();
   515     	    if( iNotifyMessage.IsNull() == EFalse )
   516     	        {
   517     	        iNotifyMessage.Complete( KErrCancel );
   518     	        }
   519             TPckgC<TInt> resPckg( KErrNone );
   520             aMessage.WriteL( 0, resPckg );
   521     	    
   522     	    break;
   523     	    }
   524     	    
   525         case EFeatMgrSWIStart:
   526     	    {
   527     	    if( getIdErr == KErrNone)  
   528     	    	{
   529     	    	getIdErr = iRegistry.SWIStart(processId);
   530 	    	    }
   531     	    TPckgC<TInt> resPckg( getIdErr );
   532             aMessage.WriteL( 0, resPckg );
   533             
   534     	    break;
   535     	    }
   536     	    
   537         case EFeatMgrSWIEnd:
   538     	    {
   539     	    if( getIdErr == KErrNone)
   540     	    	{
   541     	    	getIdErr = iRegistry.SWIEnd(processId);
   542     	    	}
   543     	    TPckgC<TInt> resPckg( getIdErr );
   544             aMessage.WriteL( 0, resPckg );
   545             
   546     		break;
   547     	    }
   548 
   549 #ifdef EXTENDED_FEATURE_MANAGER_TEST
   550     	    
   551 #pragma BullseyeCoverage off
   552     	    
   553         case EFeatMgrResourceMark:
   554             ResourceCountMarkStart();
   555             break;
   556             
   557         case EFeatMgrResourceCheck:
   558             ResourceCountMarkEnd(aMessage);
   559             break;
   560         
   561         case EFeatMgrResourceCount:
   562             {
   563             TInt retCode = CountResources();
   564             User::Leave(retCode);
   565             }
   566             break;
   567         
   568         case EFeatMgrSetHeapFailure:
   569             {
   570             RAllocator::TAllocFail mode = static_cast <RAllocator::TAllocFail> (aMessage.Int0());
   571             TInt failAllocNum = aMessage.Int1();
   572             if(mode == RHeap::EBurstFailNext || mode == RHeap::EBurstRandom || mode == RHeap::EBurstTrueRandom || mode == RHeap::EBurstDeterministic)
   573                 {
   574                 User::__DbgSetBurstAllocFail(RHeap::EUser, mode, failAllocNum, 20);
   575                 }
   576             else
   577                 {
   578                 User::__DbgSetAllocFail(RHeap::EUser, mode, failAllocNum);
   579                 }
   580             }
   581             break;
   582 
   583     	    // debug only API 
   584     	    // returns the size of the iNotifyFeatures array
   585         case EFeatMgrNumberOfNotifyFeatures:
   586     	    {
   587     	    TInt count = iNotifyFeatures.Count();
   588             TPckgC<TInt> resPckg( count );
   589             aMessage.WriteL( 0, resPckg );
   590     	    
   591     	    break;
   592     	    }
   593 
   594     	    // returns the number of allocated heap cells
   595         case EFeatMgrCountAllocCells:
   596     	    {
   597     	    TInt count = User::CountAllocCells();
   598             TPckgC<TInt> resPckg( count );
   599             aMessage.WriteL( 0, resPckg );
   600     	    
   601     	    break;
   602     	    }
   603     	    
   604 #pragma BullseyeCoverage on
   605     	    
   606 #endif
   607 
   608         // Cannot identify the message.
   609         default:
   610             {
   611             PanicClient( aMessage, EPanicIllegalArgument );
   612             break;
   613            }
   614         }
   615     }
   616 
   617 // -----------------------------------------------------------------------------
   618 // CFeatMgrSession::ServiceNotifications
   619 // -----------------------------------------------------------------------------
   620 //
   621 void CFeatMgrSession::ServiceNotifications( TFeatureServerEntry& aFeature, 
   622     TFeatureChangeType aType )
   623     {       
   624     FUNC_LOG
   625     
   626     if( !iNotifyMessage.IsNull() ) 
   627         {
   628         TInt index( iNotifyFeatures.Find( aFeature.FeatureUid() ) );
   629         
   630         if( index != KErrNotFound )
   631             {
   632             if( aType == EFeatureFeatureDeleted )
   633             	{
   634             	// The feature was deleted - won't have any more notifications
   635             	iNotifyFeatures.Remove(index);
   636             	}
   637 
   638             // Write changed feature back to client and complete request
   639             TPckgC<TInt> feature( aFeature.FeatureUid().iUid );
   640             TInt err( iNotifyMessage.Write( 0, feature ) );
   641             if( err == KErrNone )
   642                 {
   643                 iNotifyMessage.Complete( aType );
   644                 }
   645             }
   646         }
   647     }
   648 
   649 TInt CFeatMgrSession::CountResources()
   650     {
   651     return User::CountAllocCells();
   652     }
   653 
   654 // ============================= LOCAL FUNCTIONS ===============================
   655 
   656 // ============================ MEMBER FUNCTIONS ===============================
   657 
   658 // -----------------------------------------------------------------------------
   659 // CFeatMgrPendingRequest::CFeatMgrPendingRequest
   660 // C++ constructor
   661 // -----------------------------------------------------------------------------
   662 //
   663 CFeatMgrPendingRequest::CFeatMgrPendingRequest()
   664     {
   665     }
   666 
   667 // -----------------------------------------------------------------------------
   668 // CFeatMgrPendingRequest::NewL
   669 // Two-phased constructor.
   670 // -----------------------------------------------------------------------------
   671 //
   672 CFeatMgrPendingRequest* CFeatMgrPendingRequest::NewL(const RMessage2& aMessage)
   673     {
   674     FUNC_LOG
   675     CFeatMgrPendingRequest* self = new (ELeave) CFeatMgrPendingRequest;
   676     
   677     CleanupStack::PushL( self );
   678     self->ConstructL( aMessage );
   679     CleanupStack::Pop( self );
   680 
   681     return self;
   682     }
   683 
   684 // ---------------------------------------------------------
   685 // CFeatMgrPendingRequest::ConstructL
   686 // ---------------------------------------------------------
   687 //
   688 void CFeatMgrPendingRequest::ConstructL(const RMessage2& aMessage)
   689     {
   690     iMessage = aMessage;
   691     }
   692 
   693 // ---------------------------------------------------------
   694 // Destructor
   695 // ---------------------------------------------------------
   696 //
   697 CFeatMgrPendingRequest::~CFeatMgrPendingRequest()
   698     {
   699     FUNC_LOG
   700     }
   701 
   702 
   703 //  End of File