/*
* Copyright (c) 2006-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:  CCCHWakeUpEventNotifier implementation
*
*/


// INCLUDE FILES
#include <spnotifychange.h>
#include <CoreApplicationUIsSDKCRKeys.h>

#include "cchwakeupeventnotifier.h"
#include "cchwakeupeventobserver.h"
#include "cchlogger.h"
#include "cchetelnetworkstatusnotifier.h"

// EXTERNAL DATA STRUCTURES
// None

// EXTERNAL FUNCTION PROTOTYPES
// None

// CONSTANTS
const TInt KOfflineTimeout = 500000;

// MACROS
// None

// LOCAL CONSTANTS AND MACROS
// None

// MODULE DATA STRUCTURES
// None

// LOCAL FUNCTION PROTOTYPES
//None

// FORWARD DECLARATIONS
// None

// ============================= LOCAL FUNCTIONS =============================


// ============================ MEMBER FUNCTIONS =============================

// ---------------------------------------------------------------------------
// CCCHWakeUpEventNotifier::CCCHWakeUpEventNotifier
// C++ default constructor can NOT contain any code, that might leave.
// ---------------------------------------------------------------------------
//
CCchWakeUpEventNotifier::CCchWakeUpEventNotifier( 
    MCchWakeUpEventObserver& aWakeUpEventObserver ) :
    CActive( CActive::EPriorityStandard ),
    iWakeUpEventObserver( aWakeUpEventObserver )
    {
    CCHLOGSTRING( "CCchWakeUpEventNotifier::CCchWakeUpEventNotifier" );
    CActiveScheduler::Add( this );
    }

// ---------------------------------------------------------------------------
// CCchWakeUpEventNotifier::ConstructL
// Symbian 2nd phase constructor can leave.
// ---------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::ConstructL()
    {
    CCHLOGSTRING( "CCchWakeUpEventNotifier::ConstructL" );
    
    iSPSNotifier = CSPNotifyChange::NewL( *this );
    iCchEtelNetworkNotifier = CCchEtelNetworkStatusNotifier::NewL( *this );
    iOfflineRepository = CRepository::NewL( KCRUidCoreApplicationUIs );
    iOfflineTimer = CPeriodic::NewL( CPeriodic::EPriorityStandard );
    
    StartL();
    }

// ---------------------------------------------------------------------------
// CCchWakeUpEventNotifier::NewL
// Two-phased constructor.
// ---------------------------------------------------------------------------
//
CCchWakeUpEventNotifier* CCchWakeUpEventNotifier::NewL(
    MCchWakeUpEventObserver& aWakeUpEventObserver )
    {
    CCchWakeUpEventNotifier* self = CCchWakeUpEventNotifier::NewLC(
            aWakeUpEventObserver );
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// CCchWakeUpEventNotifier::NewLC
// Two-phased constructor.
// ---------------------------------------------------------------------------
//
CCchWakeUpEventNotifier* CCchWakeUpEventNotifier::NewLC(
    MCchWakeUpEventObserver& aWakeUpEventObserver )
    {
    CCchWakeUpEventNotifier* self = new (ELeave)CCchWakeUpEventNotifier(
            aWakeUpEventObserver );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// Destructor
CCchWakeUpEventNotifier::~CCchWakeUpEventNotifier()
    {
    Cancel();
    delete iOfflineTimer;
    delete iSPSNotifier;
    delete iCchEtelNetworkNotifier;
    delete iOfflineRepository;
    }

// ---------------------------------------------------------------------------
// CCchWakeUpEventNotifier::MobileNetworkNoService
// Handles mobile network events.
// ---------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::MobileNetworkNoService()
    {
    CCHLOGSTRING( "CCchWakeUpEventNotifier::MobileNetworkNoService IN" );
    
    if ( iObservationOngoing )
        {
        iWakeUpEventObserver.WakeUp();
        }
    
    CCHLOGSTRING( "CCchWakeUpEventNotifier::MobileNetworkNoService OUT" );
    }

// ---------------------------------------------------------------------------
// CCchWakeUpEventNotifier::HandleNotifyChange
// Handles change events generated by spsettings.
// ---------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::HandleNotifyChange( TServiceId /* aServiceId */ )
    {
    CCHLOGSTRING( "CCchWakeUpEventNotifier::HandleNotifyChange IN" );
    
    if ( iObservationOngoing )
        {
        iWakeUpEventObserver.WakeUp();
        }

    CCHLOGSTRING( "CCchWakeUpEventNotifier::HandleNotifyChange OUT" );
    }

// ---------------------------------------------------------------------------
// CCchWakeUpEventNotifier::HandleError
// Handles errors generated by spsettings.
// ---------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::HandleError( TInt /*aError*/ )
    {
    CCHLOGSTRING( "CCchWakeUpEventNotifier::HandleError IN OUT" );
    }

// ----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::Cancel()
//
// ----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::DoCancel()
    {
    CCHLOGSTRING("CCchWakeUpEventNotifier::DoCancel()"); 
    iOfflineRepository->NotifyCancel( KCoreAppUIsNetworkConnectionAllowed );
    iSPSNotifier->NotifyChangeCancel();
    CancelOfflineTimer();
    }

// ----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::RunL()
//
// ----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::RunL()
    {
    CCHLOGSTRING("CCchWakeUpEventNotifier::RunL() IN");
    
    iOfflineRepository->Get( 
            KCoreAppUIsNetworkConnectionAllowed, iNetworkConnectionAllowed );
    if ( ECoreAppUIsNetworkConnectionNotAllowed == iNetworkConnectionAllowed )
        {
        // Start 0.5s timer, after timeout if cellular network is still down 
        // send wakeup event to our client. Why timer -> we can avoid situtation 
        // where cellular network is down for very short period.
        if ( !iOfflineTimer->IsActive() )
            {
            CCHLOGSTRING("CCchWakeUpEventNotifier::RunL -> Start timer");
            StartOfflineTimer( CCchWakeUpEventNotifier::OfflineTimeout );
            }
        }
    
    StartL();
    
    CCHLOGSTRING("CCchWakeUpEventNotifier::RunL() OUT"); 
    }

// ----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::RunError()
//
// ----------------------------------------------------------------------------
//
TInt CCchWakeUpEventNotifier::RunError( TInt /*aError*/ )
    {
    CCHLOGSTRING("CCchWakeUpEventNotifier::RunError IN OUT"); 
    return KErrNone;
    }

// ----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::StartL()
//
// ----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::StartL()
    {
    CCHLOGSTRING("CCchWakeUpEventNotifier::StartL IN");

    iObservationOngoing = ETrue;
    if ( !IsActive() )
        {  
        RIdArray serviceIds;
        iSPSNotifier->NotifyChangeL( serviceIds );
        
        iOfflineRepository->NotifyRequest( 
                KCoreAppUIsNetworkConnectionAllowed, iStatus );
        SetActive();
        }
    
    CCHLOGSTRING("CCchWakeUpEventNotifier::StartL OUT");
    }

// ----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::StopL()
//
// ----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::Stop()
    {
    CCHLOGSTRING("CCchWakeUpEventNotifier::Stop IN");
    iObservationOngoing = EFalse;
    Cancel();
    CCHLOGSTRING("CCchWakeUpEventNotifier::Stop OUT");
    }

// -----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::StartOfflineTimer
//
// -----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::StartOfflineTimer( TInt (*aFunction)(TAny* aPtr) )
    {
    if( !iOfflineTimer->IsActive() )
        {
        iOfflineTimer->Start( 
            KOfflineTimeout , 0, TCallBack( aFunction, this ) );
        }
    }

// -----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::CancelOfflineTimer
//
// -----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::CancelOfflineTimer()
    {
    if( iOfflineTimer->IsActive() )
        {
        iOfflineTimer->Cancel();
        }
    }

// -----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::OfflineTimeout
//
// -----------------------------------------------------------------------------
//
TInt CCchWakeUpEventNotifier::OfflineTimeout( TAny* aSelf )
    {
    CCchWakeUpEventNotifier* self = 
        static_cast<CCchWakeUpEventNotifier*>( aSelf );
    self->HandleOfflineTimeout();
    return 0;
    }

// -----------------------------------------------------------------------------
// CCchWakeUpEventNotifier::HandleOfflineTimeout
//
// -----------------------------------------------------------------------------
//
void CCchWakeUpEventNotifier::HandleOfflineTimeout()
    {
    CCHLOGSTRING( "CCchWakeUpEventNotifier::HandleOfflineTimeout IN" );
    
    CancelOfflineTimer();
    iOfflineRepository->Get( 
        KCoreAppUIsNetworkConnectionAllowed, iNetworkConnectionAllowed );

    if ( ECoreAppUIsNetworkConnectionNotAllowed == iNetworkConnectionAllowed )
        {
        // Mode is still offline, send notify to our client
        iWakeUpEventObserver.WakeUp();
        }
        
    CCHLOGSTRING( "CCchWakeUpEventNotifier::HandleOfflineTimeout OUT" );
    }

// ========================== OTHER EXPORTED FUNCTIONS =======================

//  End of File

