mediator/src/Client/MediatorNotificationsBody.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mediator/src/Client/MediatorNotificationsBody.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,484 @@
+/*
+* Copyright (c) 2005 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:  An implementation for receiving command/event notifications and info.
+*
+*/
+
+
+// INCLUDE FILES
+#include    <e32base.h>
+#include    "MediatorNotificationsBody.h"
+#include    "MediatorServerClient.h"
+#include    "Debug.h"
+
+
+// CONSTANTS
+const TInt KMediatorDefaultCommandCount = 10;
+const TInt KMediatorDefaultEventCount = 10;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+CMediatorNotificationsBody::CMediatorNotificationsBody()
+    : CActive( EPriorityNormal ), 
+      iCommandArrayPtr(NULL, 0), 
+      iEventArrayPtr(NULL, 0),
+      iCategoryBuffer( iCategory ),
+      iNotificationTypeBuffer( iNotificationType ),
+      iDestroyed(NULL)
+     
+    {
+    }
+
+void CMediatorNotificationsBody::ConstructL()
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ConstructL\n"));
+    CActiveScheduler::Add( this );
+    User::LeaveIfError( iMediatorServer.Connect() );
+    }
+
+CMediatorNotificationsBody* CMediatorNotificationsBody::NewL()
+    {
+    CMediatorNotificationsBody* self = new( ELeave ) CMediatorNotificationsBody;
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+    
+CMediatorNotificationsBody::~CMediatorNotificationsBody()
+    {
+    Cancel();
+    iMediatorServer.Close();
+    iEventList.Close();
+    iCommandList.Close();
+    
+    if ( iDestroyed ) // RunL is being executed
+        {
+        *iDestroyed = ETrue;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::RunL
+//  
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorNotificationsBody::RunL()
+    {
+    TRACE(Print(_L("[Mediator Server]\t CMediatorNotificationsBody::RunL status %d\n"), iStatus.Int() ));
+    
+    if ( iStatus < 0 )  // We have an error
+        {
+        ERROR_TRACE(Print(_L("[Mediator] CMediatorNotificationsBody::RunL: iStatus=%d\n"), iStatus.Int() ) );
+        
+        // Cleanup and return
+        iCommandList.Reset();
+        iEventList.Reset();
+        return;
+        }
+    
+    // Set the flag to the member variable that is updated by the destructor 
+    // in case this instance is destroyed by observer callback.
+    // Otherwise an attempt to manipulate member data after destruction will cause a panic.
+    TBool destroyed = EFalse;
+    // iDestroyed is set individually in each case in order to prevent erros if a leave occurs
+    
+    TInt err = KErrNone;
+    
+    // Act according to notification type. NOTE! All the observer callback-calls are trapped because
+    // leave would cause a possible access violation in destructor (iDestoryed pointing to an non-existing variable)
+    switch( iNotificationType )
+        {
+        case EMediatorEventsRegistered:
+            {
+            LOG(_L("[Mediator Server]\t Events registered\n"));
+            if ( iObserver )
+                {
+                TBool fetchEvents = iStatus.Int() > iEventList.Count() ? ETrue : EFalse;
+                
+                ResizeEventListL( iStatus.Int() );
+                
+                if ( fetchEvents )
+                    {
+                    FetchEventListL();
+                    }
+                
+                iDestroyed = &destroyed;
+                TRAP( err, iObserver->MediatorEventsAddedL( iCategory.iDomain,
+                                                            iCategory.iCategory,
+                                                            iEventList ) );
+                }
+            break;
+            }
+        case EMediatorCommandsRegistered:
+            {
+            LOG(_L("[Mediator Server]\t Commands registered\n"));
+            if ( iObserver )
+                {
+                TBool fetchCommands = iStatus.Int() > iCommandList.Count() ? ETrue : EFalse;
+                
+                ResizeCommandListL( iStatus.Int() );
+                
+                if ( fetchCommands )
+                    {
+                    FetchCommandListL();
+                    }
+                
+                iDestroyed = &destroyed;    
+                TRAP( err, iObserver->MediatorCommandsAddedL( iCategory.iDomain,
+                                                              iCategory.iCategory,
+                                                              iCommandList ) );
+                }
+            break;
+            }
+        case EMediatorEventsUnregistered:
+            {
+            LOG(_L("[Mediator Server]\t Events unregistered\n"));
+            if ( iObserver )
+                {
+                TBool fetchEvents = iStatus.Int() > iEventList.Count() ? ETrue : EFalse;
+                
+                ResizeEventListL( iStatus.Int() );
+                
+                if ( fetchEvents )
+                    {
+                    FetchEventListL();
+                    }
+                
+                iDestroyed = &destroyed;    
+                TRAP( err, iObserver->MediatorEventsRemovedL( iCategory.iDomain,
+                                                              iCategory.iCategory,
+                                                              iEventList ) );
+                }
+            break;
+            }
+        case EMediatorCommandsUnregistered:
+            {
+            LOG(_L("[Mediator Server]\t Commands unregistered\n"));
+            if ( iObserver )
+                {
+                TBool fetchCommands = iStatus.Int() > iCommandList.Count() ? ETrue : EFalse;
+                
+                ResizeCommandListL( iStatus.Int() );
+                
+                if ( fetchCommands )
+                    {
+                    FetchCommandListL();
+                    }
+                
+                iDestroyed = &destroyed;    
+                TRAP( err, iObserver->MediatorCommandsRemovedL( iCategory.iDomain,
+                                                                iCategory.iCategory,
+                                                                iCommandList ) );
+                }
+            break;
+            }
+        case EMediatorCategoryUnregistered:
+            {
+            
+            LOG(_L("[Mediator Server]\t Category unregistered\n"));
+            if ( iObserver )
+                {
+                iDestroyed = &destroyed;
+                TRAP( err, iObserver->MediatorCategoryRemovedL( iCategory.iDomain,
+                                                                iCategory.iCategory ) );
+                }
+            break;
+            }
+        default:
+            {
+            LOG(_L("[Mediator Server]\t Unknown notification\n"));
+            break;
+            }
+        }
+    
+    
+    if ( err != KErrNone )
+        {
+        ERROR_TRACE(Print(_L("[Mediator] CMediatorNotificationsBody::RunL: err=%d, iNotificationType=%d\n"), err,
+                                                                                                             iNotificationType ) );
+        if ( !destroyed )
+            {
+            iDestroyed = NULL;
+            }
+            
+        User::Leave( err ); // leave now, if an observer callback caused an error
+        }
+    
+    if ( !destroyed ) // client may delete instance in observer callback
+        {
+        iDestroyed = NULL; // set to NULL, because local variable goes out of scope soon
+        // Continue receiving notifications
+        ReceiveNotificationsL();    
+        }
+    
+    }
+        
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::DoCancel
+//  
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorNotificationsBody::DoCancel()
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::DoCancel\n"));  
+    iMediatorServer.Cancel(); 
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::RegisterNotificationObserver
+//  
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CMediatorNotificationsBody::RegisterNotificationObserver( 
+            MMediatorNotifications* aObserver )
+    {
+    iObserver = aObserver;
+    //return ReceiveNotifications();
+    
+    TRAPD ( err, ReceiveNotificationsL() );
+    
+    return err;
+    }
+            
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::UnregisterNotificationObserver
+//  
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CMediatorNotificationsBody::UnregisterNotificationObserver()
+    {
+    iObserver = NULL;
+    // Empty existing arrays
+    if ( iCommandList.Count() > 0 )
+        {
+        iCommandList.Reset();
+        }
+    if ( iEventList.Count() > 0 )
+        {
+        iEventList.Reset();
+        }
+    // Cancel the show
+    return iMediatorServer.CancelNotifications();
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::GetDomains
+// Gets a list of registered domains
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CMediatorNotificationsBody::GetDomains( RDomainList& aDomains )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetDomains\n"));
+    return iMediatorServer.GetDomains( aDomains );
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::GetCategories
+// Gets a list of registered domains
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CMediatorNotificationsBody::GetCategories( TUid aDomain, 
+                                                RCategoryList& aCategories )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetCategories\n"));
+    return iMediatorServer.GetCategories( aDomain, aCategories );
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::GetEvents
+// Gets a list of registered events withing the domain/category
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CMediatorNotificationsBody::GetEvents( TUid aDomain, 
+                                            TUid aCategory,
+                                            REventList& aEvents )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetEvents\n"));
+    return iMediatorServer.GetEvents( aDomain, aCategory, aEvents );
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::GetCommands
+// Gets a list of registered commands withing the domain/category
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CMediatorNotificationsBody::GetCommands( TUid aDomain, 
+                                              TUid aCategory,
+                                              RCommandList& aCommands )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetCommands\n"));
+    return iMediatorServer.GetCommands( aDomain, aCategory, aCommands );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::ReceiveNotificationsL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+
+void CMediatorNotificationsBody::ReceiveNotificationsL()
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ReceiveNotificationsL\n"));
+    if ( IsActive() )
+        {
+        ERROR_LOG(_L("[Mediator] CMediatorNotificationsBody::ReceiveNotificationsL: User::Leave( KErrAlreadyExists )\n") );
+        User::Leave( KErrAlreadyExists );
+        }
+        
+    ResizeEventListL( KMediatorDefaultEventCount );
+    
+    ResizeCommandListL ( KMediatorDefaultCommandCount );
+    
+    // Define data return pointers
+    TInt commandArraySize = ( sizeof(MediatorService::TCommand) ) * KMediatorDefaultCommandCount; 
+    TPtr8 commandArrayPtr( (TUint8*)&iCommandList[0], commandArraySize );
+    iCommandArrayPtr.Set( commandArrayPtr );
+    
+    TInt eventArraySize = ( sizeof(MediatorService::TEvent) ) * KMediatorDefaultEventCount; 
+    TPtr8 eventArrayPtr( (TUint8*)&iEventList[0], eventArraySize );
+    iEventArrayPtr.Set( eventArrayPtr );
+    
+    SetActive();
+    
+    iMediatorServer.ReceiveNotifications( iStatus,
+                                          iCategoryBuffer, 
+                                          iNotificationTypeBuffer,
+                                          iEventArrayPtr,
+                                          iCommandArrayPtr );
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::ResizeEventListL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorNotificationsBody::ResizeEventListL( TInt aEventCount )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ResizeEventListL\n"));
+    if ( iEventList.Count() > aEventCount ) // less events has been received than space allocated
+        {
+        // suppress list
+        for ( TInt i = iEventList.Count() - 1; i >= aEventCount; i-- )
+            {
+            iEventList.Remove( i );
+            }
+        }
+    else if ( iEventList.Count() < aEventCount )  // more events than initially/previously allocated
+        {
+        // reallocate event list
+        iEventList.Reset();
+        
+        User::LeaveIfError( iEventList.Reserve( aEventCount ) );
+        
+        for ( TInt i = 0; i < aEventCount; i++ )
+            {
+            TEvent emptyEvent;
+            iEventList.Append( emptyEvent );
+            }    
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::ResizeCommandListL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorNotificationsBody::ResizeCommandListL( TInt aCommandCount )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ResizeCommandListL\n"));
+    if ( iCommandList.Count() > aCommandCount ) // less commands has been received than space allocated
+        {
+        // suppress list
+        for ( TInt i = iCommandList.Count() - 1; i >= aCommandCount; i-- )
+            {
+            iCommandList.Remove( i );
+            }
+        }
+    else if ( iCommandList.Count() < aCommandCount )  // more commands than initially/previously allocated
+        {
+        // reallocate command list
+        iCommandList.Reset();
+        
+        User::LeaveIfError( iCommandList.Reserve( aCommandCount) );
+        
+        for ( TInt i = 0; i < aCommandCount; i++ )
+            {
+            TCommand emptyCommand;
+            iCommandList.Append( emptyCommand );
+            }    
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::FetchEventListL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorNotificationsBody::FetchEventListL()
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::FetchEventListL\n"));
+    TInt eventArraySize = ( sizeof(MediatorService::TEvent) ) * iEventList.Count(); 
+    TPtr8 eventArrayPtr( (TUint8*)&iEventList[0], eventArraySize );
+    iEventArrayPtr.Set( eventArrayPtr );
+    User::LeaveIfError( iMediatorServer.FetchNotificationEventList( iEventArrayPtr ) );
+    }
+    
+// -----------------------------------------------------------------------------
+// CMediatorNotificationsBody::FetchCommandListL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorNotificationsBody::FetchCommandListL()
+    {
+    LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::FetchCommandListL\n"));
+    TInt commandArraySize = ( sizeof(MediatorService::TCommand) ) * iCommandList.Count(); 
+    TPtr8 commandArrayPtr( (TUint8*)&iCommandList[0], commandArraySize );
+    iCommandArrayPtr.Set( commandArrayPtr );
+    User::LeaveIfError( iMediatorServer.FetchNotificationCommandList( commandArrayPtr ) );
+    }
+
+// ----------------------------------------------------------------------------
+// CStartupMediatorPluginSubscriber::RunError()
+// ----------------------------------------------------------------------------
+#ifdef _DEBUG
+TInt CMediatorNotificationsBody::RunError( TInt aError )
+#else
+TInt CMediatorNotificationsBody::RunError( TInt /*aError*/ )
+#endif //_DEBUG
+    {
+    ERROR_TRACE(Print(_L("[Mediator] CMediatorNotificationsBody::RunError: err=%d\n"), aError));
+
+    // Return KErrNone to avoid panic
+    return KErrNone;
+    }
+
+//  End of File