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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
20 #include "featmgrsession.h"
21 #include "featmgrfeatureentry.h"
22 #include "featmgrdebug.h"
25 const TInt CFeatMgrPendingRequest::iOffset = _FOFF( CFeatMgrPendingRequest,iLink );
27 // LOCAL CONSTANTS AND MACROS
28 _LIT( KPanicCategory, "FeatMgrSession" );
30 // ============================= LOCAL FUNCTIONS ===============================
32 // ============================ MEMBER FUNCTIONS ===============================
34 // -----------------------------------------------------------------------------
35 // CFeatMgrSession::CFeatMgrSession
37 // -----------------------------------------------------------------------------
39 CFeatMgrSession::CFeatMgrSession( CFeatMgrServer& aServer, CFeatMgrFeatureRegistry& aRegistry )
40 : iFeatMgrServer( aServer ),
41 iRegistry( aRegistry ),
42 iList( CFeatMgrPendingRequest::iOffset )
46 // -----------------------------------------------------------------------------
47 // CFeatMgrSession::NewL
48 // Two-phased constructor.
49 // -----------------------------------------------------------------------------
51 CFeatMgrSession* CFeatMgrSession::NewL( CFeatMgrServer& aServer,
52 CFeatMgrFeatureRegistry& aRegistry )
56 CFeatMgrSession* self = new( ELeave ) CFeatMgrSession( aServer, aRegistry );
61 #ifdef EXTENDED_FEATURE_MANAGER_TEST
62 void CFeatMgrSession::CreateL()
64 iFeatMgrServer.AddSession();
68 // ---------------------------------------------------------
70 // ---------------------------------------------------------
72 CFeatMgrSession::~CFeatMgrSession()
76 iNotifyFeatures.Close();
78 while ( !iList.IsEmpty() )
80 CFeatMgrPendingRequest* pendingReq = iList.First();
81 iList.Remove( *pendingReq );
86 #ifdef EXTENDED_FEATURE_MANAGER_TEST
87 iFeatMgrServer.DropSession();
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 // -----------------------------------------------------------------------------
98 void CFeatMgrSession::PanicClient( const RMessage2& aMessage, TFeatMgrPanic aPanic )
100 INFO_LOG1( "CFeatMgrSession::PanicClient(aPanic 0x%x)", aPanic);
102 aMessage.Panic( KPanicCategory, aPanic );
105 TBool CFeatMgrSession::IsWriteOperation( const TInt aFunction ) const
109 case EFeatMgrEnableFeature:
110 case EFeatMgrDisableFeature:
111 case EFeatMgrAddFeature:
112 case EFeatMgrSetFeatureAndData:
113 case EFeatMgrSetFeatureData:
114 case EFeatMgrDeleteFeature:
115 case EFeatMgrSWIStart:
123 // -----------------------------------------------------------------------------
124 // CFeatMgrSession::ServiceL
125 // Calls request handling functions. Also traps any leaves and signals client if
127 // -----------------------------------------------------------------------------
129 void CFeatMgrSession::ServiceL( const RMessage2& aMessage )
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 ) ) )
138 if ( iFeatMgrServer.BURIsInProgress() )
140 INFO_LOG( "CFeatMgrSession::ServiceL() - backup/restore is in progress - no write operation allowed" );
141 aMessage.Complete( KErrServerBusy );
145 INFO_LOG( "CFeatMgrSession::ServiceL() - plugins not ready" );
146 CFeatMgrPendingRequest* request=NULL;
147 TRAPD(error,request=CFeatMgrPendingRequest::NewL( aMessage ));
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);
156 iList.AddLast(*request);
162 #if defined(FEATMGR_INFO_LOG_ENABLED)
163 // check memory usage
165 INFO_LOG1( "CFeatMgrSession::ServiceL() - #### Memory Available in Heap: %6d ####",
166 User::Heap().Available(biggestBlock) );
167 INFO_LOG1( "CFeatMgrSession::ServiceL() - #### Biggest block: %6d ####",
171 TRAPD( error, DispatchMessageL( aMessage ) );
173 LOG_IF_ERROR1( error, "CFeatMgrSession::ServiceL(): Error in DispatchMessageL: %d",
176 if( aMessage.Function() != EFeatMgrReqNotify )
178 aMessage.Complete( error );
183 // -----------------------------------------------------------------------------
184 // CFeatMgrSession::ServicePendingRequestsL
185 // Calls request handling functions. Also traps any leaves and signals client if
187 // -----------------------------------------------------------------------------
189 void CFeatMgrSession::ServicePendingRequestsL()
193 while ( !iList.IsEmpty() )
195 CFeatMgrPendingRequest* pendingReq = iList.First();
197 TRAPD( error, DispatchMessageL( pendingReq->iMessage ) );
199 LOG_IF_ERROR1( error, "CFeatMgrSession::ServicePendingRequestsL(): Error in DispatchMessageL: %d",
202 if( pendingReq->iMessage.Function() != EFeatMgrReqNotify )
204 pendingReq->iMessage.Complete( error );
207 iList.Remove( *pendingReq );
214 // -----------------------------------------------------------------------------
215 // CFeatMgrSession::DispatchMessageL
216 // Calls matching function of CFeatMgrServer for handling the request.
217 // -----------------------------------------------------------------------------
219 void CFeatMgrSession::DispatchMessageL( const RMessage2& aMessage )
223 INFO_LOG1( "CFeatMgrSession::DispatchMessageL(0x%x)", aMessage.Function() );
225 TInt msgCmd = aMessage.Function();
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 )
234 getIdErr = aMessage.Client(thread, EOwnerProcess);
235 if( getIdErr == KErrNone)
238 getIdErr = thread.Process(process);
239 if( getIdErr == KErrNone)
241 TProcessId prcId = process.Id();
242 processId = TUint(prcId.Id());
247 // Check command code and call appropriate function
250 case EFeatMgrFeatureSupported:
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 );
267 case EFeatMgrFeaturesSupported:
269 TInt count( aMessage.Int0() );
270 TInt responseCount( 0 );
272 CleanupClosePushL( temp );
273 temp.ReserveL( count );
275 for ( TInt i = 0; i < count; i++ )
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 );
285 // Non-existing and uninitialised feature entries are not returned.
286 if( supported != KErrNotFound && supported != KErrNotReady )
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 );
296 // Write found entries back to client
297 for ( TInt i = 0; i < responseCount; i++ )
299 TInt offset = i * sizeof(TFeatureEntry);
300 TPckgC<TFeatureEntry> pckgBack( temp[i] );
301 aMessage.WriteL( 1, pckgBack, offset );
303 CleanupStack::PopAndDestroy( &temp );
305 // Write number of found entries back to client
306 TPckgC<TInt> resPckg( responseCount );
307 aMessage.WriteL( 2, resPckg );
312 case EFeatMgrNumberOfSupportedFeatures:
314 TInt count = iRegistry.NumberOfSupportedFeatures();
315 TPckgC<TInt> resPckg( count );
316 aMessage.WriteL( 0, resPckg );
321 case EFeatMgrListSupportedFeatures:
323 RFeatureUidArray supportedFeatures;
324 CleanupClosePushL( supportedFeatures );
326 iRegistry.SupportedFeaturesL( supportedFeatures );
327 TInt count( supportedFeatures.Count() );
329 if ( aMessage.Int0() == count )
331 for ( TInt i = 0; i < count; i++ )
333 TPckg<TUid> pckg( supportedFeatures[i] );
334 TInt offset = i * sizeof(TUid);
335 aMessage.WriteL( 1, pckg, offset );
338 CleanupStack::PopAndDestroy( &supportedFeatures );
342 CleanupStack::PopAndDestroy( &supportedFeatures );
343 User::Leave( KErrServerBusy );
348 case EFeatMgrEnableFeature:
350 if( getIdErr == KErrNone )
352 TUid feature = TUid::Uid(aMessage.Int0());
353 getIdErr = iRegistry.SetFeature( feature, EFeatureSupportEnable, NULL, processId );
355 TPckgC<TInt> resPckg( getIdErr );
356 aMessage.WriteL( 1, resPckg );
361 case EFeatMgrDisableFeature:
363 if( getIdErr == KErrNone )
365 TUid feature = TUid::Uid(aMessage.Int0());
366 getIdErr = iRegistry.SetFeature( feature, EFeatureSupportDisable, NULL, processId );
368 TPckgC<TInt> resPckg( getIdErr );
369 aMessage.WriteL( 1, resPckg );
374 case EFeatMgrAddFeature:
376 if( getIdErr == KErrNone)
378 TFeatureEntry feature;
379 TPckg<TFeatureEntry> pckg( feature );
380 aMessage.ReadL( 0, pckg );
381 TFeatureServerEntry feat( feature );
382 getIdErr = iRegistry.AddFeature( feat, processId );
384 TPckgC<TInt> resPckg( getIdErr );
385 aMessage.WriteL( 1, resPckg );
390 case EFeatMgrDeleteFeature:
392 if( getIdErr == KErrNone)
394 TUid feature = TUid::Uid(aMessage.Int0());
395 getIdErr = iRegistry.DeleteFeature( feature, processId );
397 TPckgC<TInt> resPckg( getIdErr );
398 aMessage.WriteL( 1, resPckg );
403 case EFeatMgrSetFeatureAndData:
405 if( getIdErr == KErrNone)
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 );
412 TPckgC<TInt> resPckg( getIdErr );
413 aMessage.WriteL( 3, resPckg );
418 case EFeatMgrSetFeatureData:
420 if( getIdErr == KErrNone)
422 TUid feature = TUid::Uid(aMessage.Int0());
423 TUint32 data = aMessage.Int1();
424 getIdErr = iRegistry.SetFeature( feature, EFeatureSupportUntouch, &data, processId );
426 TPckgC<TInt> resPckg( getIdErr );
427 aMessage.WriteL( 2, resPckg );
432 case EFeatMgrReqNotify:
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.
439 // Message is needed for later signaling of client upon feature change.
440 if( iNotifyMessage.IsNull() )
442 iNotifyMessage = aMessage;
446 PanicClient( aMessage, EPanicNotifyRequest );
452 case EFeatMgrReqNotifyUids:
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.
459 TInt err( KErrNone );
461 // Fetch transfer buffer from client
462 TInt count( aMessage.Int0() );
463 err = iNotifyFeatures.Reserve( count );
465 if( err == KErrNone )
467 for ( TInt i = 0; i < count; i++ )
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 )
481 TPckgC<TInt> resPckg( err );
482 aMessage.WriteL( 2, resPckg );
487 case EFeatMgrReqNotifyCancel:
489 TUid feature = TUid::Uid(aMessage.Int0());
490 TInt index( iNotifyFeatures.Find( feature ) );
491 TInt err( KErrNotFound );
493 if( index != KErrNotFound )
496 iNotifyFeatures.Remove( index );
499 // If no more features to be notified, complete request.
500 if( !iNotifyFeatures.Count()
501 && iNotifyMessage.IsNull() == EFalse)
503 iNotifyMessage.Complete( KErrCancel );
506 TPckgC<TInt> resPckg( err );
507 aMessage.WriteL( 1, resPckg );
512 case EFeatMgrReqNotifyCancelAll:
514 iNotifyFeatures.Reset();
515 if( iNotifyMessage.IsNull() == EFalse )
517 iNotifyMessage.Complete( KErrCancel );
519 TPckgC<TInt> resPckg( KErrNone );
520 aMessage.WriteL( 0, resPckg );
525 case EFeatMgrSWIStart:
527 if( getIdErr == KErrNone)
529 getIdErr = iRegistry.SWIStart(processId);
531 TPckgC<TInt> resPckg( getIdErr );
532 aMessage.WriteL( 0, resPckg );
539 if( getIdErr == KErrNone)
541 getIdErr = iRegistry.SWIEnd(processId);
543 TPckgC<TInt> resPckg( getIdErr );
544 aMessage.WriteL( 0, resPckg );
549 #ifdef EXTENDED_FEATURE_MANAGER_TEST
551 #pragma BullseyeCoverage off
553 case EFeatMgrResourceMark:
554 ResourceCountMarkStart();
557 case EFeatMgrResourceCheck:
558 ResourceCountMarkEnd(aMessage);
561 case EFeatMgrResourceCount:
563 TInt retCode = CountResources();
564 User::Leave(retCode);
568 case EFeatMgrSetHeapFailure:
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)
574 User::__DbgSetBurstAllocFail(RHeap::EUser, mode, failAllocNum, 20);
578 User::__DbgSetAllocFail(RHeap::EUser, mode, failAllocNum);
584 // returns the size of the iNotifyFeatures array
585 case EFeatMgrNumberOfNotifyFeatures:
587 TInt count = iNotifyFeatures.Count();
588 TPckgC<TInt> resPckg( count );
589 aMessage.WriteL( 0, resPckg );
594 // returns the number of allocated heap cells
595 case EFeatMgrCountAllocCells:
597 TInt count = User::CountAllocCells();
598 TPckgC<TInt> resPckg( count );
599 aMessage.WriteL( 0, resPckg );
604 #pragma BullseyeCoverage on
608 // Cannot identify the message.
611 PanicClient( aMessage, EPanicIllegalArgument );
617 // -----------------------------------------------------------------------------
618 // CFeatMgrSession::ServiceNotifications
619 // -----------------------------------------------------------------------------
621 void CFeatMgrSession::ServiceNotifications( TFeatureServerEntry& aFeature,
622 TFeatureChangeType aType )
626 if( !iNotifyMessage.IsNull() )
628 TInt index( iNotifyFeatures.Find( aFeature.FeatureUid() ) );
630 if( index != KErrNotFound )
632 if( aType == EFeatureFeatureDeleted )
634 // The feature was deleted - won't have any more notifications
635 iNotifyFeatures.Remove(index);
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 )
643 iNotifyMessage.Complete( aType );
649 TInt CFeatMgrSession::CountResources()
651 return User::CountAllocCells();
654 // ============================= LOCAL FUNCTIONS ===============================
656 // ============================ MEMBER FUNCTIONS ===============================
658 // -----------------------------------------------------------------------------
659 // CFeatMgrPendingRequest::CFeatMgrPendingRequest
661 // -----------------------------------------------------------------------------
663 CFeatMgrPendingRequest::CFeatMgrPendingRequest()
667 // -----------------------------------------------------------------------------
668 // CFeatMgrPendingRequest::NewL
669 // Two-phased constructor.
670 // -----------------------------------------------------------------------------
672 CFeatMgrPendingRequest* CFeatMgrPendingRequest::NewL(const RMessage2& aMessage)
675 CFeatMgrPendingRequest* self = new (ELeave) CFeatMgrPendingRequest;
677 CleanupStack::PushL( self );
678 self->ConstructL( aMessage );
679 CleanupStack::Pop( self );
684 // ---------------------------------------------------------
685 // CFeatMgrPendingRequest::ConstructL
686 // ---------------------------------------------------------
688 void CFeatMgrPendingRequest::ConstructL(const RMessage2& aMessage)
693 // ---------------------------------------------------------
695 // ---------------------------------------------------------
697 CFeatMgrPendingRequest::~CFeatMgrPendingRequest()