tracesrv/tracecore/btrace_handler/src/TraceCoreNotifier.cpp
changeset 56 aa2539c91954
equal deleted inserted replaced
54:a151135b0cf9 56:aa2539c91954
       
     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 // Registers / unregisters notification receivers and send notifications 
       
    15 // to them when needed.
       
    16 // 
       
    17 
       
    18 #include "TraceCore.h"
       
    19 #include "TraceCoreNotifier.h"
       
    20 #include "TraceCoreNotificationReceiver.h"
       
    21 #include "TraceCoreActivation.h"
       
    22 #include "TraceCoreDebug.h"
       
    23 #include "TraceCoreConstants.h"
       
    24 #include "OstTraceDefinitions.h"
       
    25 #ifdef OST_TRACE_COMPILER_IN_USE
       
    26 #include "TraceCoreNotifierTraces.h"
       
    27 #endif
       
    28 
       
    29 #include "TraceCoreTComArgMacro.h"
       
    30 
       
    31    
       
    32 /** 
       
    33  * Constructor
       
    34  */
       
    35 DTraceCoreNotifier::DTraceCoreNotifier()
       
    36     {
       
    37     }
       
    38 
       
    39 
       
    40 /** 
       
    41  * Destructor
       
    42  */
       
    43 DTraceCoreNotifier::~DTraceCoreNotifier()
       
    44     {
       
    45     iNotificationReceiverItems.Reset();
       
    46     }
       
    47 
       
    48 /**
       
    49  * Callback for trace activation
       
    50  *
       
    51  * @param aComponentId The component ID
       
    52  * @param aGroupId The group ID
       
    53  */
       
    54 void DTraceCoreNotifier::TraceActivated( TUint32 aComponentId, TUint16 aGroupId )
       
    55     {
       
    56     //TODO assert that this method can be run only on iActivationQ thread. (assert debug)
       
    57     OstTraceExt2( TRACE_FLOW, DTRACECORENOTIFIER_TRACEACTIVATED_ENTRY, "> DTraceCoreNotifier::TraceActivated CID:0x%x GID:0x%hx", aComponentId, (TUint32) aGroupId );
       
    58    
       
    59     // Go through notification receivers
       
    60     for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
    61         {
       
    62         if ( ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
    63                 && iNotificationReceiverItems[ i ].iGroupID == aGroupId )
       
    64           || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
    65                 && iNotificationReceiverItems[ i ].iGroupID == KAllGroups ) )
       
    66             {
       
    67 
       
    68             iNotificationReceiverItems[ i ].iReceiver->TraceActivated( aComponentId, aGroupId );
       
    69             }
       
    70             //no else
       
    71         }
       
    72 	}
       
    73 	
       
    74 /**
       
    75  * Callback for trace deactivation
       
    76  *
       
    77  * @param aComponentId The componet ID
       
    78  * @param aGroupId The group ID
       
    79  */
       
    80 void DTraceCoreNotifier::TraceDeactivated( TUint32 aComponentId, TUint16 aGroupId )
       
    81     {
       
    82     OstTraceExt2( TRACE_FLOW, DTRACECORENOTIFIER_TRACEDEACTIVATED_ENTRY, "> DTraceCoreNotifier::TraceDeactivated CID:0x%x GID:0x%hx", aComponentId, (TUint32) aGroupId );
       
    83     
       
    84     // Go through notification receivers
       
    85     for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
    86         {
       
    87         if ( ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
    88                 && iNotificationReceiverItems[ i ].iGroupID ==  aGroupId )
       
    89           || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
    90                 && iNotificationReceiverItems[ i ].iGroupID == KAllGroups )
       
    91          || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
    92                 && aGroupId ==  KAllGroups ) )
       
    93             {
       
    94             
       
    95             // If whole component was deactivated, get group ID's from the notification array
       
    96             if ( aGroupId ==  KAllGroups )
       
    97             	{
       
    98             	iNotificationReceiverItems[ i ].iReceiver->TraceDeactivated( aComponentId, iNotificationReceiverItems[ i ].iGroupID  );
       
    99             	}
       
   100             
       
   101             // One group was deactivated
       
   102             else
       
   103             	{
       
   104                 iNotificationReceiverItems[ i ].iReceiver->TraceDeactivated( aComponentId, aGroupId  );
       
   105             	}
       
   106             }
       
   107         }
       
   108 	}
       
   109 
       
   110 /**
       
   111  * Callback when there is a trace error
       
   112  * 
       
   113  * @param aComponentId The component ID
       
   114  * @param aGroupId The group ID    
       
   115  * @param aError The reason for error
       
   116  */
       
   117 void DTraceCoreNotifier::TraceError( TUint32 aComponentId, TUint32 aGroupId, TInt TCOM_ARG(aError)  )
       
   118     {
       
   119     OstTraceExt3( TRACE_FLOW, DTRACECORENOTIFIER_TRACEERROR_ENTRY, "> DTraceCoreNotifier::TraceError CID:0x%x GID:0x%x Err:%d", aComponentId, aGroupId, (TInt32) aError );
       
   120     
       
   121     // Go through notification receivers
       
   122     for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
   123         {
       
   124         if ( ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
   125                 && iNotificationReceiverItems[ i ].iGroupID == aGroupId )
       
   126           || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
       
   127                 && iNotificationReceiverItems[ i ].iGroupID == KAllGroups ) )
       
   128             {
       
   129             iNotificationReceiverItems[ i ].iReceiver->TraceError( aComponentId, aGroupId, KErrArgument );
       
   130             OstTrace0( TRACE_API, DTRACECORENOTIFIER_TRACEERROR_RETURNED_FROM_NOTIFICATION_RECEIVER, "DTraceCoreNotifier::TraceError - Returned from notification receiver");
       
   131             }
       
   132             //no else
       
   133         }
       
   134     
       
   135     OstTrace0( TRACE_FLOW, DTRACECORENOTIFIER_TRACEERROR_EXIT, "< DTraceCoreNotifier::TraceError");
       
   136     }
       
   137 
       
   138 /**
       
   139  * Register notification receiver
       
   140  * 
       
   141  * @param aItem The properties of the notification receiver
       
   142  */
       
   143 TInt DTraceCoreNotifier::RegisterNotificationReceiver( TNotificationReceiverItem& aNotificationReceiverItem )
       
   144     {
       
   145     OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_REGISTERNOTIFICATIONRECEIVER_ENTRY, "> DTraceCoreNotifier::RegisterNotificationReceiver 0x%x", ( TUint )&( aNotificationReceiverItem ) );
       
   146    
       
   147     TInt err = KErrNone;
       
   148     if ( aNotificationReceiverItem.iReceiver != NULL )
       
   149         {
       
   150         TBool itemExist( EFalse );     
       
   151         // Check if already notification receiver to the combination
       
   152         for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
   153             {
       
   154             if ( iNotificationReceiverItems[ i ].iComponentID == aNotificationReceiverItem.iComponentID
       
   155                     && iNotificationReceiverItems[ i ].iGroupID == aNotificationReceiverItem.iGroupID 
       
   156                     && iNotificationReceiverItems[ i ].iReceiver == aNotificationReceiverItem.iReceiver )
       
   157                 {
       
   158                 itemExist = ETrue;
       
   159                 break;	
       
   160                 }
       
   161                 //no else
       
   162             }
       
   163 
       
   164         // If not yet receiving, append to receiver items
       
   165         if ( !itemExist )
       
   166             {      
       
   167             err = iNotificationReceiverItems.Append( aNotificationReceiverItem );
       
   168             if ( err == KErrNone )
       
   169                 {
       
   170                 OstTraceExt2( TRACE_NORMAL, DTRACECORENOTIFIER_REGISTERNOTIFICATIONRECEIVER_REGISTERED, "DTraceCoreNotifier::RegisterNotificationReceiver - Registered CID:0x%x GID:0x%x", (TUint) aNotificationReceiverItem.iComponentID, (TUint)aNotificationReceiverItem.iGroupID );
       
   171                 
       
   172                 // Send notification immediately if group is active
       
   173                 TGroupId groupId = aNotificationReceiverItem.iGroupID;
       
   174                 NotifyImmediately(aNotificationReceiverItem.iComponentID, groupId);       
       
   175                 }
       
   176             }
       
   177         // Already registered
       
   178         else
       
   179             {
       
   180             err = KErrAlreadyExists;
       
   181             }
       
   182         }
       
   183     // Item was null
       
   184     else
       
   185         {
       
   186         err = KErrArgument;
       
   187         }
       
   188         
       
   189     OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_REGISTERNOTIFICATIONRECEIVER_EXIT, "< DTraceCoreNotifier::RegisterNotificationReceiver. Err:%d", err );
       
   190     return err;
       
   191     }
       
   192 
       
   193 
       
   194 /**
       
   195 * Get registered group IDs
       
   196 *
       
   197 * @param aComponentId The componet ID
       
   198 * @param aGroupIDs The array of group IDs
       
   199 */
       
   200 void DTraceCoreNotifier::GetComponentRegisteredGroupIDs( TUint32 aComponentID, RArray< TUint >& aGroupIDs )
       
   201 	{
       
   202     OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_GETCOMPONENTREGISTEREDGROUPIDS_ENTRY, "> DTraceCoreNotifier::GetComponentRegisteredGroupIDs CID:0x%x", aComponentID );
       
   203 	
       
   204     TBool itemExist( EFalse );
       
   205     TInt err = KErrNone;
       
   206    
       
   207     // Go through notification receivers
       
   208 	for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
   209 	    {
       
   210 	    if ( iNotificationReceiverItems[ i ].iComponentID == aComponentID )
       
   211 	        {
       
   212 	        itemExist = EFalse;
       
   213 	        
       
   214 	        // Check if the item exists already
       
   215 	        for ( TInt j = 0; j < aGroupIDs.Count(); j++ )
       
   216 	            {
       
   217 	            if ( aGroupIDs[ j ] == iNotificationReceiverItems[ i ].iGroupID )
       
   218 	                {
       
   219 	                itemExist = ETrue;
       
   220 	                break;	                    	
       
   221 	                }
       
   222 	            }
       
   223             
       
   224 	        if (!itemExist)
       
   225 	            {
       
   226 	            err = aGroupIDs.Append( iNotificationReceiverItems[ i ].iGroupID );
       
   227 	            }
       
   228 	        }	
       
   229 	    }
       
   230    
       
   231 	OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_GETCOMPONENTREGISTEREDGROUPIDS_EXIT, "< DTraceCoreNotifier::GetComponentRegisteredGroupIDs - %d", err );
       
   232     
       
   233 	err++; //just to remove arm compiler warning about not using this variable when ost is compiled out
       
   234 	}
       
   235 
       
   236 
       
   237  /**
       
   238  * Unregister notification receiver
       
   239  *
       
   240  * @param aItem The properties of the notification receiver
       
   241  */
       
   242 void DTraceCoreNotifier::UnregisterNotificationReceiver( TNotificationReceiverItem& aNotificationReceiverItem )
       
   243     {
       
   244     OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_UNREGISTERNOTIFICATIONRECEIVER_ENTRY, "> DTraceCoreNotifier::UnregisterNotificationReceiver 0x%x", ( TUint )&( aNotificationReceiverItem ) );
       
   245     
       
   246     // Go through notification receivers
       
   247 	for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
   248         {
       
   249         if ( ( iNotificationReceiverItems[ i ].iComponentID == aNotificationReceiverItem.iComponentID
       
   250                 && iNotificationReceiverItems[ i ].iGroupID == aNotificationReceiverItem.iGroupID 
       
   251                 && iNotificationReceiverItems[ i ].iReceiver == aNotificationReceiverItem.iReceiver )
       
   252             ||
       
   253                 ( iNotificationReceiverItems[ i ].iComponentID == aNotificationReceiverItem.iComponentID
       
   254                         && KAllGroups == aNotificationReceiverItem.iGroupID 
       
   255                         && iNotificationReceiverItems[ i ].iReceiver == aNotificationReceiverItem.iReceiver ) )
       
   256             {            
       
   257             // Unregister notification receiver
       
   258             iNotificationReceiverItems.Remove( i );
       
   259             i--;
       
   260             }
       
   261             //no else
       
   262         }
       
   263     }
       
   264 
       
   265 
       
   266  /**
       
   267  * Unregister all traces of given notification receiver
       
   268  *
       
   269  * @param aNotificationReceiver The notification receiver to be unregistered
       
   270  */
       
   271 void DTraceCoreNotifier::UnregisterNotificationReceiver( MTraceCoreNotificationReceiver& aNotificationReceiver )
       
   272     {
       
   273     OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_UNREGISTERNOTIFICATIONRECEIVERALL_ENTRY, "> DTraceCoreNotifier::UnregisterNotificationReceiver - All IDs 0x%x", ( TUint )&( aNotificationReceiver ) );
       
   274     
       
   275     for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
       
   276 	    {
       
   277 	    if ( iNotificationReceiverItems[ i ].iReceiver == &aNotificationReceiver )
       
   278 	        {
       
   279             OstTraceExt2( TRACE_NORMAL, DTRACECORENOTIFIER_UNREGISTERNOTIFICATIONRECEIVER_UNREGISTERED_, "DTraceCoreNotifier::UnregisterNotificationReceiver - Unregistered CID:0x%x GID:0x%x", (TUint)iNotificationReceiverItems[ i ].iComponentID, (TUint)iNotificationReceiverItems[ i ].iGroupID );
       
   280             iNotificationReceiverItems.Remove( i );
       
   281 	        i--;
       
   282 	        }
       
   283 	        //no else
       
   284 	    }
       
   285 	}
       
   286 
       
   287 /**
       
   288 * Notifies immediately if group was activated
       
   289 *
       
   290 * @param aComponentID The component id
       
   291 * @param aGroupId The group id 
       
   292 */
       
   293 void DTraceCoreNotifier::NotifyImmediately( TUint32 aComponentId, TGroupId aGroupId )
       
   294    {
       
   295    OstTraceExt2( TRACE_FLOW, NOTIFY_IMMEDIATELY_ENTRY, "> DTraceCoreNotifier::NotifyImmediately. GID: 0x%x, GID: 0x%hx", aComponentId, (TUint32) aGroupId );
       
   296    
       
   297    // Send notification about activated groups immediately
       
   298    DTraceCore* traceCore = DTraceCore::GetInstance();
       
   299    if ( traceCore != NULL )
       
   300        {
       
   301        MTraceCoreActivation *activation = traceCore->GetActivation( aComponentId );
       
   302        RArray< TUint > groups = activation->GetActivatedGroups( aComponentId );
       
   303        for (TInt i = 0; i < groups.Count(); i++)
       
   304            {
       
   305            if ( aGroupId == KAllGroups || groups[ i ] == aGroupId )
       
   306                {
       
   307                OstTrace1( TRACE_BORDER , SEND_NOTIFICATION_IMMEDIATELY, "Send activation notification immediately. Group ID:%x", groups[ i ] );
       
   308                this->TraceActivated( aComponentId, groups[ i ] );
       
   309                }
       
   310            }
       
   311        }
       
   312    }
       
   313 
       
   314 
       
   315 // End of File