locationrequestmgmt/locationserver/src/EPos_CPosLocMonitorReqHandlerHub.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:35:25 +0100
branchRCL_3
changeset 55 c92d4f3c47c5
parent 54 0c2046328c85
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201027 Kit: 201035

/*
* Copyright (c) 2009 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:  	Receives the Last Known Position, Last Known Position Area requests and Empty
* 				Position Store requests from Subsessions and Sessions in the Location Server and 
*				forwards them to the respective active objects*
*/

#include <e32base.h>
#include <e32def.h>
#include "EPos_CPosLocMonitorReqHandlerHub.h"
#include <lbs/epos_lastknownlocationpskeys.h>


// ============================ CONSTANTS ===========================================================

// CONSTANTS
#ifdef _DEBUG
_LIT(KTraceFileName, "EPos_CPosLocMonitorReqHandlerHub.cpp");
#endif

const TInt KLocationServerSID=0x101f97b2;


// ============================== MEMBER FUNCTIONS ===================================================
/**
 * NewL of the Two-phased constructor.
 *
 */
CPosLocMonitorReqHandlerHub* CPosLocMonitorReqHandlerHub::NewL()
	{

	CPosLocMonitorReqHandlerHub* self = new( ELeave ) CPosLocMonitorReqHandlerHub();
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}

/**
 * C++ default constructor
 * 
 * @param aDumpInterval 
 */
CPosLocMonitorReqHandlerHub::CPosLocMonitorReqHandlerHub() 
    {

    }

/**
 * Symbian 2nd phase constructor
 */
void CPosLocMonitorReqHandlerHub::ConstructL()
	{
	
	// Establish a session with the Location Monitor - The subsessions are
	// established in the "active objects" owned by the CPosLocMonitorReqHandlerHub
	User::LeaveIfError(iLocMonSession.Connect()); 
	
	// Establish the subsession with the location monitor - As SetPositionInfoL()
	// is likely to be called whenever we have an update from the PSYs, the subsession
	// with the location monitor is created as a member variable instead of a local variable.
	iLocMonSubSession.OpenL(iLocMonSession);
	
	// Attach to the Last Known Location P&S property
	iLastKnownPosProperty.Attach(
        KPosLastKnownLocationCategory,
        KPosLastKnownLocation);
    
    // Get the last known position from loc monitor and publish it.
    TRequestStatus status;
    TPositionInfo posInfo;
    iLocMonSubSession.GetLastKnownPosition(posInfo, status);
    User::WaitForRequest(status);

    if (status.Int()==KErrNone)
        {
        PublishPosition(posInfo);
        }
	}


/**
 * Destructor
 */
CPosLocMonitorReqHandlerHub::~CPosLocMonitorReqHandlerHub()
	{
	
    delete iLastKnownPosHandler;	
    delete iLastKnownPosAreaHandler;
    delete iEmptyLastKnownPosStoreHandler;
	
	// Close the session with the Location Monitor
	if ( iLocMonSubSession.SubSessionHandle() )
		{
		iLocMonSubSession.Close();
		}
	
	// Close the session with the Location Monitor
	if ( iLocMonSession.Handle() )
		{
		iLocMonSession.Close();
		}
		
	}

/** 
 * Set Position Information (SetPositionInfo)
 * 		>> Whenever there is a position update from any of the PSYs update the 
 * 		   location monitor of this latest position.
 *
 * @param aPositionInfo The last known position.
 */
void CPosLocMonitorReqHandlerHub::SetPositionInfo( const TPositionInfo& aPositionInfo )
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::SetPositionInfoL", __LINE__)

    // check the latest position is newer than the last published position 
    TPosition newPos;
    aPositionInfo.GetPosition(newPos);
    
    // publish the position
    PublishPosition(aPositionInfo);
    // pass the position to the loc monitor.
    TInt errSetPos = iLocMonSubSession.SetLastKnownPosition(aPositionInfo);
	}

/** 
 * Get Last Known Position Request
 * 		>> Called by the subsession to request the last known position.
 *
 * @param aMessage The message containing info about the request from subsession
 */
void CPosLocMonitorReqHandlerHub::GetLastKnownPosReqL(const RMessage2& aMessage)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::GetLastKnownPosReqL", __LINE__)
	
	if (!iLastKnownPosHandler)
		{
		// The very first request with the location monitor
		iLastKnownPosHandler = CPosLastKnownPosHandler::NewL();
		}
	
	// The timeout value for this request is hardcoded in the constant 
	// KLastKnownPosTimeOut [in CPosLastKnownPosHandler]
	iLastKnownPosHandler->GetLastKnownPosL(iLocMonSession, aMessage);
	}


/** Cancel Get Last Known Position Request 
 * 		>> Called by the subsession to cancel a last knwon position request
 * @param aMessage The message containing info about the request from subsession
 */
void CPosLocMonitorReqHandlerHub::CancelGetLastKnownPosReqL(const RMessage2& aMessage)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::CancelGetLastKnownPosReqL", __LINE__)

	if (!iLastKnownPosHandler)
		{
		// The client never sent any get last known position request earlier
		if (!aMessage.IsNull())
			{
			aMessage.Complete(KErrNotFound);
			}
		}
	else
		{
		iLastKnownPosHandler->CancelGetLastKnownPosL(aMessage);
		}
	}


/** 
 * Get Last Known Position Area Request
 * 		>> Called by the subsession to request the last known position area.
 *
 * @param aMessage The message containing info about the request from subsession
 */
void CPosLocMonitorReqHandlerHub::GetLastKnownPosAreaReqL(const RMessage2& aMessage)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::GetLastKnownPosAreaReqL", __LINE__)

	if (!iLastKnownPosAreaHandler)
		{
		// The very first request with the location monitor
		iLastKnownPosAreaHandler = CPosLastKnownPosAreaHandler::NewL();
		}
	iLastKnownPosAreaHandler->GetLastKnownPosAreaL(iLocMonSession, aMessage);

	}


/** Cancel Get Last Known Position Area Request 
 * 		>> Called by the subsession to cancel a LKPosArea request
 * @param aMessage The message containing info about the request from subsession
 */
void CPosLocMonitorReqHandlerHub::CancelGetLastKnownPosAreaReqL(const RMessage2& aMessage)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::CancelGetLastKnownPosAreaReqL", __LINE__)

	if (!iLastKnownPosAreaHandler)
		{
		// The client never sent any get last known position area request earlier
		if (!aMessage.IsNull())
			{
			aMessage.Complete(KErrNotFound);
			}
		}
	else
		{
		iLastKnownPosAreaHandler->CancelGetLastKnownPosAreaL(aMessage);
		}
	}

/** 
 * Empty Last Known Position Store Request (EmptyPositionStoreReq)
 *		>> Called by the subsession to Empty the last known position store
 *
 *  @param aMessage The message containing info about the request from subsession
 */
void CPosLocMonitorReqHandlerHub::EmptyLastKnownPosStoreReqL(const RMessage2& aMessage)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::EmptyLastKnownPosStoreL", __LINE__)
	
	if (!iEmptyLastKnownPosStoreHandler)
		{
		// The very first request with the location monitor
		iEmptyLastKnownPosStoreHandler = CPosEmptyLastKnownPosStoreHandler::NewL();
		}
	
	iEmptyLastKnownPosStoreHandler->EmptyLastKnownPosStoreL(iLocMonSession, aMessage);

	// Cancel outstanding last known position or last known position area requests
	if (iLastKnownPosAreaHandler)
		{
		iLastKnownPosAreaHandler->NotifyOnEmptyLastKnownPosStoreReq();
		}
	
	if (iLastKnownPosHandler)
		{
		iLastKnownPosHandler->NotifyOnEmptyLastKnownPosStoreReq();
		}
	
	}


/** Cancel Empty Last Known Position Store Request 
 * 		>> Called by the subsession to cancel an earlier EmptyLastKnownPosStoreReq
 * @param aMessage The message containing info about the request from subsession
 */
void CPosLocMonitorReqHandlerHub::CancelEmptyLastKnownPosStoreReqL(const RMessage2& aMessage)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::CancelGetLastKnownPosAreaReqL", __LINE__)
	
	iEmptyLastKnownPosStoreHandler->CancelEmptyLastKnownPosStoreL(aMessage);
	}


/** 
 * NotifyServerShutDown
 * 		>> Notification from the Session that the server is going to shutdown
 * 
 */
void CPosLocMonitorReqHandlerHub::NotifyServerShutDown()
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::NotifyServerShutDown", __LINE__)
	
	if (iLastKnownPosAreaHandler)
		{
		iLastKnownPosAreaHandler->NotifyServerShutDown();
		}
	
	if (iLastKnownPosHandler)
		{
		iLastKnownPosHandler->NotifyServerShutDown();
		}
	
	if (iEmptyLastKnownPosStoreHandler)
		{
		iEmptyLastKnownPosStoreHandler->NotifyServerShutDown();
		}
	}

/** 
 * NotifySubSessionClosed
 * 		>> Notification from the Session that the subsessions are to be closed
 * 
 */
void CPosLocMonitorReqHandlerHub::NotifySubSessionClosed(const RMessage2& aMessage)
	{

	if (iLastKnownPosHandler)
		{
		iLastKnownPosHandler->NotifySubSessionClosed(aMessage);
		}
	
	if (iLastKnownPosAreaHandler)
		{
		iLastKnownPosAreaHandler->NotifySubSessionClosed(aMessage);
		}
	// No need to notify the emptylastknownpositionstore request as it is issued on a 
	// session and not a subsession
	}

/** 
 * NotifySessionClosed
 * 		>> Notification from the Session that it is going to be closed 
 *		NOTE : Not guaranteed that the requests would be completed with EPositoinRequestsNotCancelled
 * 			   - This method is used to ensure that the request queue is cleaned up
 * @param aSessionPtr The Session pointer
 */
void CPosLocMonitorReqHandlerHub::NotifySessionClosed(const CSession2* aSessionPtr)
	{
	DEBUG_TRACE("CPosLocMonitorReqHandlerHub::NotifySessionClosed", __LINE__)
	
	if (iLastKnownPosAreaHandler)
		{
		iLastKnownPosAreaHandler->NotifySessionClosed(aSessionPtr);
		}
	
	if (iLastKnownPosHandler)
		{
		iLastKnownPosHandler->NotifySessionClosed(aSessionPtr);
		}
	
	if (iEmptyLastKnownPosStoreHandler)
		{
		iEmptyLastKnownPosStoreHandler->NotifySessionClosed(aSessionPtr);
		}
	
	}


/** 
 * PublishPosition
 *      >> Publishes the position to the Last Known Position P&S Property
 *       
 */
void CPosLocMonitorReqHandlerHub::PublishPosition(const TPositionInfo& aPositionInfo)
    {
    TPckg<TPositionInfo> positionDes( aPositionInfo );
    TInt err = iLastKnownPosProperty.Set(positionDes);
    if(err == KErrNotFound)
        {
        __ASSERT_DEBUG(EFalse, DebugPanic(EPosServerPanicLastKnownPosPnsNotDefined));
        // The key is not defined. This should not happen in normal case.
        // However, if this happens, we define the key again
        _LIT_SECURITY_POLICY_C1(readPolicy, ECapabilityReadDeviceData);
        _LIT_SECURITY_POLICY_S0(writePolicy, KLocationServerSID);
        //Error code ignored
        iLastKnownPosProperty.Define(
            KPosLastKnownLocationCategory,
            KPosLastKnownLocation,
            RProperty::EText,
            readPolicy,
            writePolicy);
        }
    }