diff -r a151135b0cf9 -r aa2539c91954 tracesrv/tracecore/btrace_handler/src/TraceCoreNotifier.cpp --- /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