locationrequestmgmt/networkrequesthandler/src/EPos_CPosDialogCtrl.cpp
changeset 0 9cfd9a3ee49c
child 18 54d74d217042
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationrequestmgmt/networkrequesthandler/src/EPos_CPosDialogCtrl.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,688 @@
+// Copyright (c) 2005-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:
+//
+
+
+
+// INCLUDE FILES
+#include <s32mem.h>
+#include <lbs/epos_privacy.h>
+#include <lbs/epos_cposcontactrequestor.h>
+#include <lbs/epos_cposservicerequestor.h>
+#include <lbs/epos_rposrequestorstack.h>
+#include <lbs/epos_privacynotifier.hrh>
+#include "EPos_CPosDialogCtrl.h"
+#include <lbs/lbslocclasstypes.h>
+
+// CONSTANTS
+#if defined(NRH_UNIT_TEST)
+// For the NRH unit test, use a different Q&N notifier implementation UID.
+// This is so that we can have both the unit test Q&N notifier and
+// the integration test Q&N notifier (with the real implementation UID)
+// in the same ROM.
+const TUid KNotifierUid = { 0x10283744 };
+#else
+const TUid KNotifierUid = { KPosPrivacyNotifierImplUid };
+#endif // NRH_UNIT_TEST
+
+// The output descriptor for Notifier calls. Since we want to pass
+// just a dummy null descriptor there is no need to create a HBufC
+// each time.
+TPtr8 nullPtr(reinterpret_cast<TUint8*>(NULL), 0);
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CPosDialogCtrl::CPosDialogCtrl() : CActive(EPriorityNormal),
+    iRequestQueue(1) // Set granularity to 1
+    {
+    CActiveScheduler::Add(this);
+    }
+
+// EPOC default constructor can leave.
+void CPosDialogCtrl::ConstructL()
+    {
+    TInt err = iNotifier.Connect();
+    User::LeaveIfError(err);
+    }
+
+// Two-phased constructor.
+CPosDialogCtrl* CPosDialogCtrl::InstanceL()
+    {
+    CPosDialogCtrl* self = new (ELeave) CPosDialogCtrl;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// Destructor
+CPosDialogCtrl::~CPosDialogCtrl()
+    {
+    Cancel();
+    TInt count = iRequestQueue.Count();
+    for (TInt i = 0; i < count; i++)
+        {
+        DoCompleteRequest(0, KErrServerTerminated);
+        }
+
+    iNotifier.Close();
+    iRequestQueue.Close();
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::NotifyL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::NotifyL(
+	TLbsExternalRequestInfo& aRequestInfo,
+    const TPosRequestData& aRequestData)
+    {
+    TRequest request;
+    request.iType = TPosQNInputData::ENotification;
+    request.iRequestInfo = &aRequestInfo;
+    request.iStatus = NULL;
+    request.iRequestSource = aRequestData.iRequestSource;
+    request.iTimeoutStrategy = aRequestData.iTimeoutStrategy;
+    request.iRequestDecision = aRequestData.iRequestDecision;
+    request.iCancelReason = aRequestData.iCancelReason;
+    request.iNotificationReason = aRequestData.iNotificationReason;
+
+    ScheduleRequestL(request);
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::VerifyL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::VerifyL(
+    TRequestStatus& aStatus,
+	TLbsExternalRequestInfo& aRequestInfo,
+    const TPosRequestData& aRequestData)
+    {
+    aStatus = KRequestPending;
+
+    TRequest request;
+    request.iType = TPosQNInputData::EQuery;
+    request.iRequestInfo = &aRequestInfo;
+    request.iStatus = &aStatus;
+    request.iRequestSource = aRequestData.iRequestSource;
+    request.iTimeoutStrategy = aRequestData.iTimeoutStrategy;
+    request.iRequestDecision = aRequestData.iRequestDecision;
+    request.iCancelReason = aRequestData.iCancelReason;
+    request.iNotificationReason = aRequestData.iNotificationReason;
+
+    GivePriorityToVerificationL(request);
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::CancelLaunch
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::CancelLaunch(TRequestStatus& aStatus)
+    {
+    TInt count = iRequestQueue.Count();
+
+    if (count > 0 && iRequestQueue[0].iStatus == &aStatus)
+        {
+        Cancel();
+        DoCompleteRequest(0, KErrCancel);
+        NextRequest();
+        }
+    else
+        {
+        for (TInt i = 1; i < count; ++i)
+            {
+            if (iRequestQueue[i].iStatus == &aStatus)
+                {
+                DoCompleteRequest(i, KErrCancel);
+                return;
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::CancelLaunch
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::CancelLaunch(
+    TRequestStatus& aStatus,
+    TInt& aErrorCode,
+    TInt& aResponse,
+    TBool& aRequestQueued,
+    TPosVerifyCancelReason aCancelReason)
+    {
+    TInt count = iRequestQueue.Count();
+
+    if (count > 0 && iRequestQueue[0].iStatus == &aStatus)
+        {
+        TPtr8 nullPtr(reinterpret_cast<TUint8*>(NULL), 0);
+        TPosQNInputData data;
+        data.iId = iRequestQueue[0].iId;
+        data.iCancelReason = aCancelReason;
+
+        TPckg<TPosQNInputData> dataPtr(data);
+
+        aErrorCode = iNotifier.UpdateNotifier(KNotifierUid, dataPtr, nullPtr);
+        if( KErrNone==aErrorCode  /* && iRequestQueue[0].iTimeoutStrategy == EPosDecisionAccepted  */)  
+	        {
+	        // If there is an error, notifications will be triggered through PrivManager
+	        TRAPD(err,CreateNotificationAndEnqueueL());
+	        err = err; // To avoid compiler warning
+	        }
+        aResponse = iStatus.Int();
+        aRequestQueued = EFalse;
+        }
+    else
+        {
+        aResponse = KErrNone;
+        aErrorCode = KErrNone;
+        aRequestQueued = ETrue;
+        }
+    CancelLaunch(aStatus);
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::RunL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::RunL()
+    {
+    if (iRequestQueue.Count() > 0)
+        {
+        DoCompleteRequest(0, iStatus.Int());
+        NextRequest();
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::DoCancel
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::DoCancel()
+    {
+    if (iStatus == KRequestPending)
+        {
+        iNotifier.CancelNotifier(KNotifierUid);
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::DialogActive
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CPosDialogCtrl::DialogActive() const
+    {
+    return iRequestQueue.Count() > 0;
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::NextRequest
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::NextRequest()
+    {
+    while (iRequestQueue.Count() > 0)
+        {
+        TInt err = StartNotifierRequest();
+        if (err)
+            {
+            DoCompleteRequest(0, err);
+            }
+        else
+            {
+            return;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::DoCompleteRequest
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::DoCompleteRequest(
+    TInt aIndex,
+    TInt aCompletionCode)
+    {
+    TRequest request = iRequestQueue[aIndex];
+    if (request.iType == TPosQNInputData::ENotification)
+        {
+        delete request.iRequestInfo;
+        }
+    else
+        {
+        TRequestStatus* status = request.iStatus;
+        User::RequestComplete(status, aCompletionCode);
+        }
+    iRequestQueue.Remove(aIndex);
+    iRequestQueue.Compress();
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::ScheduleRequestL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::ScheduleRequestL(TRequest& aRequest)
+    {
+    // Start a new request.    
+    aRequest.iId = ++iRequestId;
+    User::LeaveIfError(iRequestQueue.Append(aRequest));
+
+    if (iRequestQueue.Count() == 1)
+        {
+        TInt err = StartNotifierRequest();
+
+        if (err != KErrNone)
+            {
+            DoCompleteRequest(0, err);
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::StartNotifierRequest
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TInt CPosDialogCtrl::StartNotifierRequest()
+    {
+    TRequest request = iRequestQueue[0];
+    
+    // Convert the TLbsExternalRequestInfo into a CPosRequestorStack
+    RPosRequestorStack reqStack;
+    TRAPD(err, ExtractRequestorsL(*request.iRequestInfo, reqStack));
+    if (err != KErrNone)
+    	{
+    	return err;
+    	}
+    TInt dataSize = CalcSize(reqStack);
+
+    HBufC8* reqStackBuf = HBufC8::New(dataSize);
+    if (!reqStackBuf)
+        {
+        reqStack.ResetAndDestroy();
+        return KErrNoMemory;
+        }
+
+    TPtr8 ptr = reqStackBuf->Des();
+    TRAP(err, CreateSerializedStackL(ptr, reqStack));
+    if (err == KErrNone)
+        {
+        TPosQNInputData data;
+        data.iId = request.iId;
+        data.iType = request.iType;
+        data.iDataSize = dataSize;
+        data.iDataPtr = NULL;
+        data.iRequestSource = request.iRequestSource;
+        data.iTimeoutStrategy = request.iTimeoutStrategy;
+        data.iRequestDecision = request.iRequestDecision;
+        data.iNotificationReason = request.iNotificationReason;
+        data.iCancelReason = request.iCancelReason;
+
+        TPckg<TPosQNInputData> dataPtr(data);
+
+        HBufC8* buffer = HBufC8::New(KPosQNInputDataClassSize +
+            reqStackBuf->Size());
+        if (!buffer)
+            {
+            delete reqStackBuf;
+            return KErrNoMemory;
+            }
+
+        buffer->Des().Append(dataPtr);
+        buffer->Des().Append(*reqStackBuf);
+
+        delete reqStackBuf;
+        reqStackBuf = NULL;
+
+        iNotifier.StartNotifierAndGetResponse(
+            iStatus, KNotifierUid, nullPtr, nullPtr);
+        SetActive();
+
+        err = iNotifier.UpdateNotifier(KNotifierUid, *buffer, nullPtr);
+        if (err != KErrNone)
+            {
+            Cancel();
+            }
+        delete buffer;
+        }
+
+    delete reqStackBuf;
+    reqStack.ResetAndDestroy();
+    return err;
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::CreateSerializedStackL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::CreateSerializedStackL(
+    TDes8& aBuffer,
+    const RPosRequestorStack& aRequestStack)
+    {
+    RDesWriteStream writeStream(aBuffer);
+    CleanupClosePushL(writeStream);
+    aRequestStack.ExternalizeL(writeStream);
+    writeStream.CommitL();
+    CleanupStack::PopAndDestroy(1, &writeStream);
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::CalcSize
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TInt CPosDialogCtrl::CalcSize(
+    const RPosRequestorStack& aRequestStack)
+    {
+    TInt size = sizeof(TInt);	// One TInt for number of requestors.
+    const TInt numRequestors = aRequestStack.Count();
+    for (TInt i = 0; i < numRequestors; i++)
+    	{
+    	const CPosRequestor* requestor = aRequestStack[i];
+    	
+    	// Add on the size of the requestor class, the 
+    	// descriptor it contains, and an extra TInt which
+    	// is used to store the length of the descriptor.
+    	size += sizeof(CPosRequestor);
+    	size += sizeof(TInt);
+    	size += requestor->RequestorIdString().Size();
+    	}
+
+    return size;
+    }
+
+/** Convert a TLbsExternalRequestInfo into a RPosRequestorStack.
+ */
+void CPosDialogCtrl::ExtractRequestorsL(
+ 		const TLbsExternalRequestInfo& aRequestInfo,
+     	RPosRequestorStack& aRequestors)
+ 	{	
+ 	// Convert the Client name into a CPosRequestor::ERequestorService requestor.
+ 	switch (aRequestInfo.ClassType())
+ 		{
+ 		case EExternalRequestInfoClass:
+ 			{
+ 			TBuf<KLbsMaxClientNameSize> buf;
+ 			aRequestInfo.GetClientName(buf);
+ 			AddRequestorL(CPosRequestor::ERequestorService,
+ 						  aRequestInfo.ClientNameFormat(),
+ 						  aRequestInfo.RequestType(),
+ 						  aRequestInfo.NetworkType(),
+ 						  buf,
+ 						  aRequestors
+ 						  );
+ 			break;
+ 			}
+ 		case (EExternalRequestInfoClass 
+ 			  | EExternalRequestInfoClass2):
+ 		  	{
+   			const TLbsExternalRequestInfo2& info = static_cast<const TLbsExternalRequestInfo2&>(aRequestInfo);
+   			TBuf<KLbsMaxClientNameSize2> buf;
+ 			info.GetClientName(buf);
+ 			AddRequestorL(CPosRequestor::ERequestorService,
+ 						  aRequestInfo.ClientNameFormat(),
+ 						  aRequestInfo.RequestType(),
+ 						  aRequestInfo.NetworkType(),
+ 						  buf,
+ 						  aRequestors
+ 						  );		
+ 		  	break;
+ 		  	}
+ 		default:
+ 			{
+ 			// Unrecognised TLbsExternalRequestInfo class type, so ignore it.
+ 			break;
+ 			}
+ 		}	
+ 	
+ 	// Convert the Requestor name into a CPosRequestor::ERequestorContact requestor.
+ 	switch (aRequestInfo.ClassType())
+ 		{
+ 		case EExternalRequestInfoClass:
+ 			{
+ 			TBuf<KLbsMaxRequesterIdSize> buf;
+ 			aRequestInfo.GetRequesterId(buf);
+ 			AddRequestorL(CPosRequestor::ERequestorContact,
+ 						  aRequestInfo.RequesterIdFormat(),
+ 						  aRequestInfo.RequestType(),
+ 						  aRequestInfo.NetworkType(),
+ 						  buf,
+ 						  aRequestors
+ 						  );
+ 			break;
+ 			}
+ 		case (EExternalRequestInfoClass 
+ 			  | EExternalRequestInfoClass2):
+ 		  	{
+   			const TLbsExternalRequestInfo2& info = static_cast<const TLbsExternalRequestInfo2&>(aRequestInfo);
+   			TBuf<KLbsMaxRequesterIdSize2> buf;
+ 			info.GetRequesterId(buf);
+ 			AddRequestorL(CPosRequestor::ERequestorContact,
+ 						  aRequestInfo.RequesterIdFormat(),
+ 						  aRequestInfo.RequestType(),
+ 						  aRequestInfo.NetworkType(),
+ 						  buf,
+ 						  aRequestors
+ 						  );
+ 		  	break;
+ 		  	}
+ 		default:
+ 			{
+ 			// Unrecognised TLbsExternalRequestInfo class type, so ignore it.
+ 			break;
+ 			}
+ 		}
+ 	}
+
+ /**
+ */	
+void CPosDialogCtrl::AddRequestorL(
+ 		CPosRequestor::TRequestorType aRequestorType,
+ 		TLbsExternalRequestInfo::TFormatIndicator aIdType,
+ 	    CPosRequestor::TRequestType aRequestType,
+ 	    CPosRequestor::TNetworkType aNetworkType,
+ 		const TDesC& aId,
+ 		RPosRequestorStack& aRequestors)
+ 	{
+ 	CPosRequestor::TRequestorIdFormat format = CPosRequestor::EIdFormatUnknown;
+ 	switch (aIdType)
+ 		{
+ 		case TLbsExternalRequestInfo::EFormatLogicalName :
+ 			format = CPosRequestor::EIdFormatGenericName;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatMSISDN :
+ 			format = CPosRequestor::EIdFormatPhoneNumber;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatEmailAddress :
+ 			format = CPosRequestor::EIdFormatEmail;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatURL :
+ 			format = CPosRequestor::EIdFormatUrl;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatSIPURL :
+ 			format = CPosRequestor::EIdFormatSIPUrl;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatIMSPublicIdentity :
+ 			format = CPosRequestor::EIdFormatIMSPublicIdentity;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatMIN:
+ 			format = CPosRequestor::EIdFormatMIN;
+ 			break;
+ 		case TLbsExternalRequestInfo::EFormatMDN:
+ 			format = CPosRequestor::EIdFormatMDN;
+ 			break;
+ 		}
+
+ 	// Only add the requestor to the stack if it is a recognised format.
+ 	if (format != CPosRequestor::EIdFormatUnknown)
+ 		{
+ 	    CPosRequestor* requestor = NULL;
+ 	    if (aRequestorType == CPosRequestor::ERequestorContact)
+ 	        {
+ 	        requestor = CPosContactRequestor::NewLC(format, aId);
+ 	        }
+ 	    else
+ 	        {
+ 	        requestor = CPosServiceRequestor::NewLC(format, aId);
+ 	        }
+ 	        
+ 	    requestor->SetRequestType(aRequestType);
+ 	    requestor->SetNetworkType(aNetworkType);
+     	User::LeaveIfError(aRequestors.Append(requestor));
+     	CleanupStack::Pop(requestor);
+ 		}	
+ 	}
+ 
+ 
+// ---------------------------------------------------------
+// CPosDialogCtrl::GivePriorityToVerificationL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::GivePriorityToVerificationL(TRequest& aRequest)
+    {
+    TBool notificationDeferred = EFalse;
+    
+    if( iRequestQueue.Count() == 0 )
+	    {
+	    ScheduleRequestL(aRequest);
+	    return;
+	    }
+	if ( iRequestQueue[0].iType == TPosQNInputData::ENotification )
+		{
+		notificationDeferred=ETrue; // To indicate that notification is deferred,dont remove it from queue.
+		}
+		
+	EnqueueRequestL(aRequest);
+	
+	if(notificationDeferred)
+		{
+		Cancel();	
+	    DeferNotificationL();
+		}
+    }
+// ---------------------------------------------------------
+// CPosDialogCtrl::EnqueueRequestL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::EnqueueRequestL(TRequest& aRequest)
+    {
+    aRequest.iId = ++iRequestId;
+    
+    for( TInt i = 1; i < iRequestQueue.Count(); i++ )
+		{
+		if ( iRequestQueue[i].iType == TPosQNInputData::ENotification )
+			{
+			User::LeaveIfError(iRequestQueue.Insert( aRequest,i ));
+			return;
+			}
+		}
+	
+    User::LeaveIfError(iRequestQueue.Append(aRequest));
+    }
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::DeferNotificationL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::DeferNotificationL()
+	{
+	if( KErrCancel == iStatus.Int() )
+		{
+		//Notification request has been cancelled..Defer it by adding 
+		// after verification requests,remove it from first place & schedule next request.
+		TRequest request = iRequestQueue[0];
+		EnqueueRequestL(request);
+		}
+	iRequestQueue.Remove(0);
+    iRequestQueue.Compress();
+	NextRequest();	
+	}
+
+// ---------------------------------------------------------
+// CPosDialogCtrl::CreateNotificationAndEnqueueL
+//
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CPosDialogCtrl::CreateNotificationAndEnqueueL()
+	{   
+    TRequest verifyRequest = iRequestQueue[0];   
+    TRequest notifyRequest;
+    TLbsExternalRequestInfo* requestinfocopy = NULL;
+    
+    if (verifyRequest.iRequestInfo->ClassType() == EExternalRequestInfoClass) 
+        {        
+        requestinfocopy = new (ELeave) TLbsExternalRequestInfo;
+        CleanupStack::PushL(requestinfocopy);
+        Mem::Copy(requestinfocopy, verifyRequest.iRequestInfo, sizeof(TLbsExternalRequestInfo));
+        }
+    else 
+        {
+        __ASSERT_DEBUG(verifyRequest.iRequestInfo->ClassType() == EExternalRequestInfoClass | EExternalRequestInfoClass2, User::Invariant());
+        requestinfocopy = new (ELeave) TLbsExternalRequestInfo2;
+        CleanupStack::PushL(requestinfocopy);
+        Mem::Copy(requestinfocopy, verifyRequest.iRequestInfo, sizeof(TLbsExternalRequestInfo2));        
+        }
+
+    notifyRequest.iRequestInfo = requestinfocopy;    
+    notifyRequest.iType = TPosQNInputData::ENotification;
+    notifyRequest.iStatus = NULL;
+    notifyRequest.iRequestSource = EPosRequestSourceNetwork;
+    
+    notifyRequest.iTimeoutStrategy = EPosDecisionNotAvailable;
+    notifyRequest.iRequestDecision = verifyRequest.iTimeoutStrategy;
+    
+    notifyRequest.iCancelReason = EPosCancelReasonTimeout; 
+    notifyRequest.iNotificationReason = EPosVerificationTimeout;
+    
+    EnqueueRequestL(notifyRequest);        
+    CleanupStack::Pop(requestinfocopy);
+    
+	}
+//  End of File