genericpositioningplugins/locationnpppsy/src/npppsyrequester.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 23 Jun 2010 18:40:52 +0300
changeset 32 b12ea03c50a3
parent 0 667063e416a2
permissions -rw-r--r--
Revision: 201023 Kit: 2010125

/*
* Copyright (c) 2006 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:  This is NPP PSY Positioning Plug-in ( PSY ).
*
*/



// INCLUDE FILES
#include <e32std.h>            
#include <lbspositioninfo.h>      // TPositionInfoBase
#include <lbs/epos_cpositioner.h> // CPositioner

#include "npppsypositioner.h"
#include "npppsysingletonhandler.h"
#include "npppsysettinghandler.h"
#include "npppsystatushandler.h"
#include "npppsyrequester.h"
#include "npppsylogging.h"
#include "npppsypanic.h"
#include "npppsy.hrh"



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

// -----------------------------------------------------------------------------
// CNppPsyRequester::CNppPsyRequester
// C++default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CNppPsyRequester::CNppPsyRequester( CNppPsyPositioner& aPositioner )
    : CActive( CActive::EPriorityStandard ),
      iNppPsyPositioner( aPositioner )
    {
    CActiveScheduler::Add( this );
    }


// -----------------------------------------------------------------------------
// CNppPsyRequester::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CNppPsyRequester::ConstructL()
    {
    TRACESTRING( "CNppPsyRequester::ConstructL start" )
    
    //Singleton handler
    iSingletonHandler = CNppPsySingletonHandler::GetInstanceL( 
        iNppPsyPositioner.StatusReportInterface() );
    
    TRACESTRING( "CNppPsyRequester::ConstructL end" )
    }


// -----------------------------------------------------------------------------
// CNppPsyRequester::NewL
// Two - phased constructor.
// -----------------------------------------------------------------------------
//
CNppPsyRequester* CNppPsyRequester::NewL( CNppPsyPositioner& aPositioner )
    {
    CNppPsyRequester* self = new( ELeave ) CNppPsyRequester( aPositioner );
    
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );

    return self;
    }

    
// -----------------------------------------------------------------------------
// CNppPsyRequester::~CNppPsyRequester
// 
// -----------------------------------------------------------------------------
//
CNppPsyRequester::~CNppPsyRequester()
    {
    Cancel();
    
    iPsyList.Close();
    delete iPositioner;
    
    if ( iSingletonHandler )
        {
        iSingletonHandler->ReleaseInstance();
        }
        
    TRACESTRING( "CNppPsyRequester:: destructed" )
    }


// -----------------------------------------------------------------------------
// CNppPsyRequester::NotifyPositionUpdate
// 
// -----------------------------------------------------------------------------
//
void CNppPsyRequester::NotifyPositionUpdate ( 
    TPositionInfoBase& aPosInfo,  
    TRequestStatus&    aStatus )
    {
    TRACESTRING( "CNppPsyRequester::NotifyPositionUpdate start" )

    //NPP PSY will not handle simultaneous location request
    if ( iRequestStatus )
        {
        Panic( EPanicPositionRequestOngoing );
        }
    
    //Report the request is made
    iSingletonHandler->StatusHandler().IncRequestCount();

    aStatus = KRequestPending;
    iRequestStatus = &aStatus;
    iPositionInfo = &aPosInfo;
    
    //Get PSY list
    TRAPD( err, iSingletonHandler->SettingHandler().GetPsyListL( iPsyList ) );
    if ( err == KErrNone )
        {
        if ( iPsyList.Count() == 0 )
            {
            //Empty PSY List
            CompleteRequest( KPositionQualityLoss );
            }
        else
            {
            MakeLocationRequest();
            }
        }
    else
        {
        CompleteRequest( err );
        }
        
    TRACESTRING( "CNppPsyRequester::NotifyPositionUpdate end" )
    }



// -----------------------------------------------------------------------------
// CNppPsyRequester::RunL
// -----------------------------------------------------------------------------
//
void CNppPsyRequester::RunL()
    {
    //Partial update is not possible for network based positioning
    if ( iStatus.Int() == KErrNone )
        {
        CompleteRequest( KErrNone );
        }
    else
        {
        //Try next PSY
        if ( iStatus.Int() < 0 && iStatus != KErrCancel )
            {
            //Move Psy to last.
            iSingletonHandler->SettingHandler().MovePsyLast( iPsyList[0] );
            //iPsyList can't be empty
            }
            
            //Remove this PSY from list
            iPsyList.Remove( 0 );
            
            //Try next PSY
            MakeLocationRequest();
        }
    }

// -----------------------------------------------------------------------------
// CNppPsyRequester::DoCancel
// -----------------------------------------------------------------------------
//
void CNppPsyRequester::DoCancel()
    {
    if ( iRequestStatus )
        {
        CompleteRequest( KErrCancel );
        }
    
    if ( iPositioner )
        {
        iPositioner->CancelNotifyPositionUpdate();
        }
    }

// -----------------------------------------------------------------------------
// CNppPsyRequester::RunError
// -----------------------------------------------------------------------------
//
TInt CNppPsyRequester::RunError( TInt /*aErr*/ )
    {
    //shall not be called.
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// CNppPsyRequester::MakeLocationRequest
// -----------------------------------------------------------------------------
//
void CNppPsyRequester::MakeLocationRequest()
    {
    //Get the uid of the first PSY
    if ( iPsyList.Count() == 0 )
        {
        //List is empty
        TInt preError = iStatus.Int();
        preError = preError == KErrNone?KErrNotFound:preError;
        CompleteRequest( preError );
        return;
        }

    TUid impUid = iPsyList[0];
    
    TInt err( KErrNone );
    
    //Load PSY
    if ( !iPositioner || iPositioner->ImplementationUid() != impUid )
        {
        if ( iPositioner )
            {
            iPositioner->CancelNotifyPositionUpdate();
            }
            
        delete iPositioner;
        iPositioner = NULL;
        
        TRAP( err,
            iPositioner =
                CPositioner::NewL( impUid, iNppPsyPositioner ) );
        
        if ( err == KErrNotFound )
            {
            //Psy uid is in the list but psy is not found in system
            iSingletonHandler->SettingHandler().RemovePsy( impUid ); 
            //error ignored.
            }
        }
    

    if ( err == KErrNone )
        {
        iStatus = KRequestPending;
        iPositioner->NotifyPositionUpdate( *iPositionInfo, iStatus );
        SetActive();
        }
    else
        {
        //Report the first psy failure
        iStatus = KRequestPending;
        SetActive();
        TRequestStatus* status = &iStatus;
        User::RequestComplete( status, err );
        }
    }


// -----------------------------------------------------------------------------
// CNppPsyRequester::CompleteRequest
// -----------------------------------------------------------------------------
//
void CNppPsyRequester::CompleteRequest( TInt aErr )
    {
    //Set UID before complete the request
    iPositionInfo->SetModuleId( TUid::Uid( KNppPsyImplUid ) );
    User::RequestComplete( iRequestStatus, aErr );

    //Report the request is completed
    iSingletonHandler->StatusHandler().DecRequestCount();
    }

//  End of File