tracesrv/tracecore/btrace_handler/src/TraceCoreNotifier.cpp
changeset 56 aa2539c91954
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tracesrv/tracecore/btrace_handler/src/TraceCoreNotifier.cpp	Fri Oct 08 14:56:39 2010 +0300
@@ -0,0 +1,315 @@
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Registers / unregisters notification receivers and send notifications 
+// to them when needed.
+// 
+
+#include "TraceCore.h"
+#include "TraceCoreNotifier.h"
+#include "TraceCoreNotificationReceiver.h"
+#include "TraceCoreActivation.h"
+#include "TraceCoreDebug.h"
+#include "TraceCoreConstants.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "TraceCoreNotifierTraces.h"
+#endif
+
+#include "TraceCoreTComArgMacro.h"
+
+   
+/** 
+ * Constructor
+ */
+DTraceCoreNotifier::DTraceCoreNotifier()
+    {
+    }
+
+
+/** 
+ * Destructor
+ */
+DTraceCoreNotifier::~DTraceCoreNotifier()
+    {
+    iNotificationReceiverItems.Reset();
+    }
+
+/**
+ * Callback for trace activation
+ *
+ * @param aComponentId The component ID
+ * @param aGroupId The group ID
+ */
+void DTraceCoreNotifier::TraceActivated( TUint32 aComponentId, TUint16 aGroupId )
+    {
+    //TODO assert that this method can be run only on iActivationQ thread. (assert debug)
+    OstTraceExt2( TRACE_FLOW, DTRACECORENOTIFIER_TRACEACTIVATED_ENTRY, "> DTraceCoreNotifier::TraceActivated CID:0x%x GID:0x%hx", aComponentId, (TUint32) aGroupId );
+   
+    // Go through notification receivers
+    for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+        {
+        if ( ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && iNotificationReceiverItems[ i ].iGroupID == aGroupId )
+          || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && iNotificationReceiverItems[ i ].iGroupID == KAllGroups ) )
+            {
+
+            iNotificationReceiverItems[ i ].iReceiver->TraceActivated( aComponentId, aGroupId );
+            }
+            //no else
+        }
+	}
+	
+/**
+ * Callback for trace deactivation
+ *
+ * @param aComponentId The componet ID
+ * @param aGroupId The group ID
+ */
+void DTraceCoreNotifier::TraceDeactivated( TUint32 aComponentId, TUint16 aGroupId )
+    {
+    OstTraceExt2( TRACE_FLOW, DTRACECORENOTIFIER_TRACEDEACTIVATED_ENTRY, "> DTraceCoreNotifier::TraceDeactivated CID:0x%x GID:0x%hx", aComponentId, (TUint32) aGroupId );
+    
+    // Go through notification receivers
+    for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+        {
+        if ( ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && iNotificationReceiverItems[ i ].iGroupID ==  aGroupId )
+          || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && iNotificationReceiverItems[ i ].iGroupID == KAllGroups )
+         || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && aGroupId ==  KAllGroups ) )
+            {
+            
+            // If whole component was deactivated, get group ID's from the notification array
+            if ( aGroupId ==  KAllGroups )
+            	{
+            	iNotificationReceiverItems[ i ].iReceiver->TraceDeactivated( aComponentId, iNotificationReceiverItems[ i ].iGroupID  );
+            	}
+            
+            // One group was deactivated
+            else
+            	{
+                iNotificationReceiverItems[ i ].iReceiver->TraceDeactivated( aComponentId, aGroupId  );
+            	}
+            }
+        }
+	}
+
+/**
+ * Callback when there is a trace error
+ * 
+ * @param aComponentId The component ID
+ * @param aGroupId The group ID    
+ * @param aError The reason for error
+ */
+void DTraceCoreNotifier::TraceError( TUint32 aComponentId, TUint32 aGroupId, TInt TCOM_ARG(aError)  )
+    {
+    OstTraceExt3( TRACE_FLOW, DTRACECORENOTIFIER_TRACEERROR_ENTRY, "> DTraceCoreNotifier::TraceError CID:0x%x GID:0x%x Err:%d", aComponentId, aGroupId, (TInt32) aError );
+    
+    // Go through notification receivers
+    for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+        {
+        if ( ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && iNotificationReceiverItems[ i ].iGroupID == aGroupId )
+          || ( iNotificationReceiverItems[ i ].iComponentID == aComponentId 
+                && iNotificationReceiverItems[ i ].iGroupID == KAllGroups ) )
+            {
+            iNotificationReceiverItems[ i ].iReceiver->TraceError( aComponentId, aGroupId, KErrArgument );
+            OstTrace0( TRACE_API, DTRACECORENOTIFIER_TRACEERROR_RETURNED_FROM_NOTIFICATION_RECEIVER, "DTraceCoreNotifier::TraceError - Returned from notification receiver");
+            }
+            //no else
+        }
+    
+    OstTrace0( TRACE_FLOW, DTRACECORENOTIFIER_TRACEERROR_EXIT, "< DTraceCoreNotifier::TraceError");
+    }
+
+/**
+ * Register notification receiver
+ * 
+ * @param aItem The properties of the notification receiver
+ */
+TInt DTraceCoreNotifier::RegisterNotificationReceiver( TNotificationReceiverItem& aNotificationReceiverItem )
+    {
+    OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_REGISTERNOTIFICATIONRECEIVER_ENTRY, "> DTraceCoreNotifier::RegisterNotificationReceiver 0x%x", ( TUint )&( aNotificationReceiverItem ) );
+   
+    TInt err = KErrNone;
+    if ( aNotificationReceiverItem.iReceiver != NULL )
+        {
+        TBool itemExist( EFalse );     
+        // Check if already notification receiver to the combination
+        for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+            {
+            if ( iNotificationReceiverItems[ i ].iComponentID == aNotificationReceiverItem.iComponentID
+                    && iNotificationReceiverItems[ i ].iGroupID == aNotificationReceiverItem.iGroupID 
+                    && iNotificationReceiverItems[ i ].iReceiver == aNotificationReceiverItem.iReceiver )
+                {
+                itemExist = ETrue;
+                break;	
+                }
+                //no else
+            }
+
+        // If not yet receiving, append to receiver items
+        if ( !itemExist )
+            {      
+            err = iNotificationReceiverItems.Append( aNotificationReceiverItem );
+            if ( err == KErrNone )
+                {
+                OstTraceExt2( TRACE_NORMAL, DTRACECORENOTIFIER_REGISTERNOTIFICATIONRECEIVER_REGISTERED, "DTraceCoreNotifier::RegisterNotificationReceiver - Registered CID:0x%x GID:0x%x", (TUint) aNotificationReceiverItem.iComponentID, (TUint)aNotificationReceiverItem.iGroupID );
+                
+                // Send notification immediately if group is active
+                TGroupId groupId = aNotificationReceiverItem.iGroupID;
+                NotifyImmediately(aNotificationReceiverItem.iComponentID, groupId);       
+                }
+            }
+        // Already registered
+        else
+            {
+            err = KErrAlreadyExists;
+            }
+        }
+    // Item was null
+    else
+        {
+        err = KErrArgument;
+        }
+        
+    OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_REGISTERNOTIFICATIONRECEIVER_EXIT, "< DTraceCoreNotifier::RegisterNotificationReceiver. Err:%d", err );
+    return err;
+    }
+
+
+/**
+* Get registered group IDs
+*
+* @param aComponentId The componet ID
+* @param aGroupIDs The array of group IDs
+*/
+void DTraceCoreNotifier::GetComponentRegisteredGroupIDs( TUint32 aComponentID, RArray< TUint >& aGroupIDs )
+	{
+    OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_GETCOMPONENTREGISTEREDGROUPIDS_ENTRY, "> DTraceCoreNotifier::GetComponentRegisteredGroupIDs CID:0x%x", aComponentID );
+	
+    TBool itemExist( EFalse );
+    TInt err = KErrNone;
+   
+    // Go through notification receivers
+	for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+	    {
+	    if ( iNotificationReceiverItems[ i ].iComponentID == aComponentID )
+	        {
+	        itemExist = EFalse;
+	        
+	        // Check if the item exists already
+	        for ( TInt j = 0; j < aGroupIDs.Count(); j++ )
+	            {
+	            if ( aGroupIDs[ j ] == iNotificationReceiverItems[ i ].iGroupID )
+	                {
+	                itemExist = ETrue;
+	                break;	                    	
+	                }
+	            }
+            
+	        if (!itemExist)
+	            {
+	            err = aGroupIDs.Append( iNotificationReceiverItems[ i ].iGroupID );
+	            }
+	        }	
+	    }
+   
+	OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_GETCOMPONENTREGISTEREDGROUPIDS_EXIT, "< DTraceCoreNotifier::GetComponentRegisteredGroupIDs - %d", err );
+    
+	err++; //just to remove arm compiler warning about not using this variable when ost is compiled out
+	}
+
+
+ /**
+ * Unregister notification receiver
+ *
+ * @param aItem The properties of the notification receiver
+ */
+void DTraceCoreNotifier::UnregisterNotificationReceiver( TNotificationReceiverItem& aNotificationReceiverItem )
+    {
+    OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_UNREGISTERNOTIFICATIONRECEIVER_ENTRY, "> DTraceCoreNotifier::UnregisterNotificationReceiver 0x%x", ( TUint )&( aNotificationReceiverItem ) );
+    
+    // Go through notification receivers
+	for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+        {
+        if ( ( iNotificationReceiverItems[ i ].iComponentID == aNotificationReceiverItem.iComponentID
+                && iNotificationReceiverItems[ i ].iGroupID == aNotificationReceiverItem.iGroupID 
+                && iNotificationReceiverItems[ i ].iReceiver == aNotificationReceiverItem.iReceiver )
+            ||
+                ( iNotificationReceiverItems[ i ].iComponentID == aNotificationReceiverItem.iComponentID
+                        && KAllGroups == aNotificationReceiverItem.iGroupID 
+                        && iNotificationReceiverItems[ i ].iReceiver == aNotificationReceiverItem.iReceiver ) )
+            {            
+            // Unregister notification receiver
+            iNotificationReceiverItems.Remove( i );
+            i--;
+            }
+            //no else
+        }
+    }
+
+
+ /**
+ * Unregister all traces of given notification receiver
+ *
+ * @param aNotificationReceiver The notification receiver to be unregistered
+ */
+void DTraceCoreNotifier::UnregisterNotificationReceiver( MTraceCoreNotificationReceiver& aNotificationReceiver )
+    {
+    OstTrace1( TRACE_FLOW, DTRACECORENOTIFIER_UNREGISTERNOTIFICATIONRECEIVERALL_ENTRY, "> DTraceCoreNotifier::UnregisterNotificationReceiver - All IDs 0x%x", ( TUint )&( aNotificationReceiver ) );
+    
+    for ( TInt i = 0; i < iNotificationReceiverItems.Count(); i++ )
+	    {
+	    if ( iNotificationReceiverItems[ i ].iReceiver == &aNotificationReceiver )
+	        {
+            OstTraceExt2( TRACE_NORMAL, DTRACECORENOTIFIER_UNREGISTERNOTIFICATIONRECEIVER_UNREGISTERED_, "DTraceCoreNotifier::UnregisterNotificationReceiver - Unregistered CID:0x%x GID:0x%x", (TUint)iNotificationReceiverItems[ i ].iComponentID, (TUint)iNotificationReceiverItems[ i ].iGroupID );
+            iNotificationReceiverItems.Remove( i );
+	        i--;
+	        }
+	        //no else
+	    }
+	}
+
+/**
+* Notifies immediately if group was activated
+*
+* @param aComponentID The component id
+* @param aGroupId The group id 
+*/
+void DTraceCoreNotifier::NotifyImmediately( TUint32 aComponentId, TGroupId aGroupId )
+   {
+   OstTraceExt2( TRACE_FLOW, NOTIFY_IMMEDIATELY_ENTRY, "> DTraceCoreNotifier::NotifyImmediately. GID: 0x%x, GID: 0x%hx", aComponentId, (TUint32) aGroupId );
+   
+   // Send notification about activated groups immediately
+   DTraceCore* traceCore = DTraceCore::GetInstance();
+   if ( traceCore != NULL )
+       {
+       MTraceCoreActivation *activation = traceCore->GetActivation( aComponentId );
+       RArray< TUint > groups = activation->GetActivatedGroups( aComponentId );
+       for (TInt i = 0; i < groups.Count(); i++)
+           {
+           if ( aGroupId == KAllGroups || groups[ i ] == aGroupId )
+               {
+               OstTrace1( TRACE_BORDER , SEND_NOTIFICATION_IMMEDIATELY, "Send activation notification immediately. Group ID:%x", groups[ i ] );
+               this->TraceActivated( aComponentId, groups[ i ] );
+               }
+           }
+       }
+   }
+
+
+// End of File