--- /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