calendarui/controller/src/calennotifier.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:13:43 +0300
branchRCL_3
changeset 29 12af337248b1
parent 28 96907930389d
child 30 bd7edf625bdd
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2007 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:  Calendar notifier
*
*/


//system includes
#include <e32property.h>
#include <bacntf.h>                   // CEnvironmentChangeNotifier
#include <coemain.h>                  // EActivePriorityLogonA

//user includes
#include "calendarui_debug.h"
#include "calennotifier.h"            // CalenNotifier
#include "calenstatemachine.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "calennotifierTraces.h"
#endif

const TInt KHashLength = 64;

// ----------------------------------------------------------------------------
// CalenNotifier::CalenNotifier
// C++ default constructor.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
CalenNotifier::CalenNotifier( CCalenStateMachine& aStateMachine )
    : iStateMachine( aStateMachine )
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_CALENNOTIFIER_ENTRY );
    
    OstTraceFunctionExit0( CALENNOTIFIER_CALENNOTIFIER_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::~CalenNotifier
// Destructor.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
CalenNotifier::~CalenNotifier()
    {
    OstTraceFunctionEntry0( DUP1_CALENNOTIFIER_CALENNOTIFIER_ENTRY );
    
    // Reset the handler array.
    // Before we reset , close hashset for each handler
    for(TInt i = 0 ; i < iHandlers.Count() ; i++)
        {
        iHandlers[i].iHashSet.Close();
        }
    
    iHandlers.Reset();
    iBroadcastQueue.Reset();
    
    // Stop environment change notifications
    if( iEnvChangeNotifier )
        {
        iEnvChangeNotifier->Cancel();
        delete iEnvChangeNotifier;
        }

    OstTraceFunctionExit0( DUP1_CALENNOTIFIER_CALENNOTIFIER_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::ConstructL
// Symbian 2nd phase of construction.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::ConstructL()
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_CONSTRUCTL_ENTRY );
    
    // Register for system environment changes
    TCallBack envCallback( EnvChangeCallbackL, this );
    iEnvChangeNotifier =
        CEnvironmentChangeNotifier::NewL( EActivePriorityLogonA, envCallback );
    iEnvChangeNotifier->Start();

    iIgnoreFirstLocaleChange = ETrue;
 
    OstTraceFunctionExit0( CALENNOTIFIER_CONSTRUCTL_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::RegisterForNotificationsL
// Adds the passed handler to the handler array.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::RegisterForNotificationsL( MCalenNotificationHandler* aHandler, 
                                                TCalenNotification aNotification)
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_REGISTERFORNOTIFICATIONSL_ENTRY );
    
    TNotificationHandler handler;
    handler.iHandler = aHandler;
    
    //Prepare hash
    handler.iHashSet.ReserveL(KHashLength);
    
    if(ECalenNotifyAll == aNotification)
        {
        //ECalenNotifyAll indicates that all notifications to be registered
        //iterate through TCalenNotification enum and add the notifications to iHashSet
         
        for(TCalenNotification notificationIter = TCalenNotification(ECalenNotifyAll + 1); 
                                notificationIter < ECalenNotifyLast; 
                                notificationIter = TCalenNotification(notificationIter + 1))
            {
            handler.iHashSet.InsertL(notificationIter);
            }
        }
    else
        {
        //Add only single notification.
        handler.iHashSet.InsertL(aNotification);
        }
    
    iHandlers.Append( handler );
    
    OstTraceFunctionExit0( CALENNOTIFIER_REGISTERFORNOTIFICATIONSL_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::RegisterForNotificationsL
// Adds the passed handler to the handler array.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::RegisterForNotificationsL( MCalenNotificationHandler* aHandler, 
                                                           RArray<TCalenNotification>& aNotifications  )
    {
    OstTraceFunctionEntry0( DUP1_CALENNOTIFIER_REGISTERFORNOTIFICATIONSL_ENTRY );

    TNotificationHandler handler;
    handler.iHandler = aHandler;
    
    //Prepare hash
    handler.iHashSet.ReserveL(KHashLength);
    
    if(aNotifications.Find(ECalenNotifyAll) != KErrNotFound)
        {
        //ECalenNotifyAll indicates that all notifications to be registered
        //If ECalenNotifyAll is found in aNotifications along with other notifications
        //iterate through TCalenNotification enum and add the notifications to iHashSet
        for(TCalenNotification notificationIter = TCalenNotification(ECalenNotifyAll + 1); 
                                    notificationIter < ECalenNotifyLast; 
                                    notificationIter = TCalenNotification(notificationIter + 1))
            {
            handler.iHashSet.InsertL(notificationIter);
            }
        }
    else
        {
        //Add notifocations from Array(aNotifications) into iHashSet member 
        for(TInt i = 0 ; i < aNotifications.Count() ; i++)
            {
            handler.iHashSet.InsertL(aNotifications[i]);
            }
        }
    
    iHandlers.Append( handler );

    OstTraceFunctionExit0( DUP1_CALENNOTIFIER_REGISTERFORNOTIFICATIONSL_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::CancelNotifications
// Removes the passed handler from the handler array.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::CancelNotifications( MCalenNotificationHandler* aHandler )
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_CANCELNOTIFICATIONS_ENTRY );
    
    for( TInt x = 0; x < iHandlers.Count(); ++x )
        {
        if( iHandlers[x].iHandler == aHandler )
            {
            // Mark the notification for deletion by
            // settings the handler to NULL. Actual deletion
            // will take place in DoBroadcast
            iHandlers[x].iHashSet.Close();
            iHandlers[x].iHandler = NULL;
            TRACE_EXIT_POINT;
            OstTraceFunctionExit0( CALENNOTIFIER_CANCELNOTIFICATIONS_EXIT );
            return;
            }
        }

    OstTraceFunctionExit0( DUP1_CALENNOTIFIER_CANCELNOTIFICATIONS_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::ContextChanged
// From MCalenContextChangeObserver. Called when the context changes.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::ContextChanged()
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_CONTEXTCHANGED_ENTRY );
    
    BroadcastNotification( ECalenNotifyContextChanged );

    OstTraceFunctionExit0( CALENNOTIFIER_CONTEXTCHANGED_EXIT );
    }

// ----------------------------------------------------------------------------
//  CCalenNotifier::EnvChangeCallbackL
//  CEnvironmentChangeNotifier callback.  Calendar is only interested in:
//  EChangesLocale              - System locale changed
//  EChangesMidnightCrossover   - System time passed midnight
//  EChangesSystemTime          - System time changed
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CalenNotifier::EnvChangeCallbackL( TAny* aThisPtr )
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_ENVCHANGECALLBACKL_ENTRY );
    
    OstTraceFunctionExit0( CALENNOTIFIER_ENVCHANGECALLBACKL_EXIT );
    
    // Return value for functions used as TCallBack objects should be EFalse
    // unless the function is intended to be called again from a timer.
   // return EFalse;
    return static_cast<CalenNotifier*>(aThisPtr)->DoEnvChange();
    }

// ----------------------------------------------------------------------------
//  CCalenNotifier::DoEnvChange
//  EnvChangeCallbackL calls this function
// ----------------------------------------------------------------------------
//
TInt CalenNotifier::DoEnvChange()
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_DOENVCHANGE_ENTRY );
    
    if( ((iEnvChangeNotifier->Change() & EChangesMidnightCrossover)
        || (iEnvChangeNotifier->Change() & EChangesSystemTime))
        && !iIgnoreFirstLocaleChange )
        {
        BroadcastNotification( ECalenNotifySystemTimeChanged );
        }
    else if( (iEnvChangeNotifier->Change() & EChangesLocale)
            && !iIgnoreFirstLocaleChange )  
        {
        BroadcastNotification( ECalenNotifySystemLocaleChanged );
        }
     else
        {
        iIgnoreFirstLocaleChange = EFalse;
        }   

    OstTraceFunctionExit0( CALENNOTIFIER_DOENVCHANGE_EXIT );
    return EFalse ;
    }

// ----------------------------------------------------------------------------
// CalenNotifier::BroadcastNotification
// Issues a notification to all registered handlers
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::BroadcastNotification( TCalenNotification aNotification )
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_BROADCASTNOTIFICATION_ENTRY );
    
    // Someone has told us to broadcast, or one of our notifiers completed.
    // We run it past the state machine and that may or may not call the
    // function to really do the broadcast.
    iStateMachine.HandleNotification( aNotification );
    
    OstTraceFunctionExit0( CALENNOTIFIER_BROADCASTNOTIFICATION_EXIT );
    }
    
// ----------------------------------------------------------------------------
// CalenNotifier::BroadcastApprovedNotification
// Issues a notification to all registered handlers
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::BroadcastApprovedNotification( TCalenNotification aNotification )
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_BROADCASTAPPROVEDNOTIFICATION_ENTRY );
    
    iBroadcastQueue.Append( aNotification );

    if( !iBroadcastActive )
        {
        iBroadcastActive = ETrue;
        while( iBroadcastQueue.Count() )
            {
            TCalenNotification notification = iBroadcastQueue[0];
            DoBroadcast( notification );
            iBroadcastQueue.Remove( 0 );
            }
        iBroadcastActive = EFalse;
        }
    
    OstTraceFunctionExit0( CALENNOTIFIER_BROADCASTAPPROVEDNOTIFICATION_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::DoBroadcast
// Issues a notification to all registered handlers
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CalenNotifier::DoBroadcast( TCalenNotification aNotification )
    {
    OstTraceFunctionEntry0( CALENNOTIFIER_DOBROADCAST_ENTRY );
    
    for( TInt x = 0; x < iHandlers.Count(); ++x )
        {
        TNotificationHandler handler = iHandlers[x];
        if( handler.iHandler )
            {
             if( handler.iHashSet.Find(aNotification) )
                {
                handler.iHandler->HandleNotification( aNotification );
                }
            }
        else
            {
            // The handler has been marked for deletion
            iHandlers.Remove( x ); // remove the entry
            --x; // decrement the index.
            }
        }

    OstTraceFunctionExit0( CALENNOTIFIER_DOBROADCAST_EXIT );
    }

// ----------------------------------------------------------------------------
// CalenNotifier::TNotificationHandler()
// TNotificationHandler contructor
// ----------------------------------------------------------------------------
CalenNotifier::TNotificationHandler::TNotificationHandler() : 
                iHashSet(&::HashCalenNotificationFunction,&::HashCalenNotificationIdentityRelation)
    {
    OstTraceFunctionEntry0( TNOTIFICATIONHANDLER_TNOTIFICATIONHANDLER_ENTRY );
    
    OstTraceFunctionExit0( TNOTIFICATIONHANDLER_TNOTIFICATIONHANDLER_EXIT );
    }

// End of file