--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/locationsystemui/locationsysui/locverifier/src/lpdverifierplugin.cpp Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,1232 @@
+/*
+ * Copyright (c) 2002 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: Verifier plug-in which derives from CPosPrivacyNotifier.
+ *
+ */
+
+// INCLUDE FILES
+#include <eikenv.h>
+#include <eiknotapi.h>
+#include <AknIconArray.h>
+#include <apgcli.h>
+#include <lbs/epos_rposrequestorstack.h>
+#include <epos_csuplsettingsconstants.h>
+#include <StringLoader.h>
+#include <locverifierdlg.rsg>
+#include "lpdverifierplugin.h"
+#include "lpdrequestao.h"
+#include "lpdrequestorprocessor.h"
+#include "lpdverifierquerylauncher.h"
+#include "lpdnotifierquerylauncher.h"
+#include "lpdbasemodel.h"
+#include "locconsts.h"
+#include "locverifierdlgdebug.h"
+#include "locfileutils.h"
+#include "locrequestorutilsresolver.h"
+#include "lpdperiodicprocessor.h"
+
+// INCLUDE FILES
+#include <s32mem.h>
+#include "locphonenumberformat.h"
+#include "locverifiercoverui.h"
+// CONSTANTS
+
+// The Increment size for the package buffer used for packing the descriptors
+const TInt KReqBufferIncrSize = 256;
+const TInt KLpdItemArrayGranularity = 50;
+
+const TInt KNonPeriodicRequest = 0;
+const TInt KPeriodicRequest = 1;
+
+const TInt KNotifyMessageLength = 300;
+
+// CONSTANTS
+
+// Unnamed namespace for local definitions
+
+const MEikSrvNotifierBase2::TNotifierPriority KNotifierPriority =
+ MEikSrvNotifierBase2::ENotifierPriorityHigh;
+const TUid KNotifierChannel =
+ {
+ 0x100065ac
+ };
+_LIT_SECURE_ID(KUikonSrvSecureId,0x10003a4a);
+#ifdef _DEBUG
+_LIT( KPanicText, "CLpdVerifierPlugin" );
+enum TPanicCode
+ {
+ KLpdErrGeneral = 1
+ };
+#endif
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::CLpdVerifierPlugin
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLpdVerifierPlugin::CLpdVerifierPlugin() :
+ iCurrentRequest(KPosNullQNRequestId), iPeriodicNotQue(
+ KLpdItemArrayGranularity)
+
+ {
+ iEnv = CEikonEnv::Static();
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::ConstructL()
+ {
+ BaseConstructL(KNotifierChannel, KNotifierPriority);
+
+ TFileName* resourceFile = new (ELeave) TFileName;
+ CleanupStack::PushL(resourceFile);
+ // these appends are always safe:
+ resourceFile->Append(KLocNotifierRscPath);
+ resourceFile->Append(KLocVerifierRscFileName);
+ TFileName* dllDrive = new (ELeave) TFileName;
+ CleanupStack::PushL(dllDrive);
+ Dll::FileName(*dllDrive);
+ LocFileUtils::GetNearestLanguageFileL(iEnv->FsSession(), *dllDrive,
+ *resourceFile);
+ CleanupStack::PopAndDestroy(dllDrive);
+ iResourceOffset = iEnv->AddResourceFileL(*resourceFile);
+ CleanupStack::PopAndDestroy(resourceFile);
+
+ iRtorProcessor = CLpdRequestorProcessor::NewL();
+ iPeriodicProcessor = CLpdPeriodicProcessor::NewL( *this );
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CLpdVerifierPlugin* CLpdVerifierPlugin::NewL()
+ {
+ CLpdVerifierPlugin* self = new (ELeave) CLpdVerifierPlugin;
+
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+
+ return self;
+ }
+
+// Destructor
+CLpdVerifierPlugin::~CLpdVerifierPlugin()
+ {
+ // Destruction of this plugin should only occur only in shutdown
+ // or in severe problem situation.
+
+ // A very special scenario is that base class construction leaves and
+ // this destructor is called. In that case CompleteAllRequests() causes
+ // access violation (noticed this by checking source code of base class).
+ if (NotifierBase())
+ { // base class has been fully constructed, method call is safe
+ CompleteAllRequests(KErrGeneral);
+ }
+
+ // It is enough to delete queries so when don't get callbacks.
+ FreeQueryResources();
+ iPeriodicNotQue.Close();
+ delete iPeriodicProcessor;
+ delete iRequestActiveObject;
+ delete iRtorProcessor;
+ iEnv->DeleteResourceFile(iResourceOffset);
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNewRequestL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNewRequestL(TPosQNRequestId aRequestId)
+ {
+ EnqueIfPeriodicL(aRequestId);
+ // Check whether the notifier is already handling a request
+ // If yes, do nothing for now.
+ if (iRequestActiveObject)
+ {
+ return;
+ }
+ else
+ {
+ iRequestActiveObject = CLpdRequestAO::NewL(*this);
+ iRequestActiveObject->ScheduleRequest();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::EnqueIfPeriodicL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::EnqueIfPeriodicL(TPosQNRequestId aRequestId)
+ {
+ SetCurrentRequestL(aRequestId);
+ TRequestType requestType = RequestTypeL(aRequestId);
+ CPosRequestor::TRequestType requestorType = CheckRequestTypeL();
+
+ if (requestType == ENotification && requestorType
+ == CPosRequestor::ERequestPeriodic)
+ {
+ TInt64 sessionId = -1;
+ GetSessionIdL( sessionId );
+
+ TLpdPeriodicReqInfo newReq(aRequestId, sessionId);
+
+ if (iPeriodicProcessor)
+ {
+ if (iPeriodicProcessor->GetSessionId() == sessionId)
+ {
+ CompleteRequest(aRequestId, KErrNone);
+ }
+ return;
+ }
+ else
+ {
+ TIdentityRelation<TLpdPeriodicReqInfo> matcher(
+ TLpdPeriodicReqInfo::MatchSession);
+ TInt index = iPeriodicNotQue.Find(newReq, matcher);
+
+ // Remove if it was present in Que
+ if (index == KErrNotFound)
+ {
+ iPeriodicNotQue.Append(newReq);
+ }
+ else
+ {
+ CompleteRequest(aRequestId, KErrNone);
+ }
+ }
+ }
+
+ if (KPosNullQNRequestId != iCurrentRequest)
+ SetCurrentRequestL(iCurrentRequest);
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleRequestCancelled
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleRequestCancelled(TPosQNRequestId aRequestId)
+ {
+ // Check whether the request is coming from Uikon Server.
+ // If not reject this request.
+ if (!CheckClientSecureId(KUikonSrvSecureId))
+ {
+ return;
+ }
+
+ // This method is called for Verification Query Cancellation.
+ // There are 2 scenarios when the cancellation can come.
+ // 1. The verification query for which the cancellation is done is
+ // currently is running
+ // 2. The verification query is not running currently but is in the
+ // requests Queue maintained by the base class.
+ //
+ // Case 1 :
+ //
+ // If there is a Verification query currently running and the requestId
+ // matches then the cancel notificaiton has to be popped up.
+ //
+ // Case 2 :
+ //
+ // 1. A Verification query was popped up.
+ // 2. The network timed out and sent a cancel request which popped
+ // up a notification request.
+ // 3. The network sends another verification query in the mean time
+ // and also cancels it. The resulting notification dialog will
+ // not be run since there is still a notification that has not
+ // been dismissed by the user.
+ //
+ // Hence in case 2 the notification information is maintained in a Que
+ // in the iRequestActiveObject. Once the current notification dialog
+ // closes and there are no more verification dialogs pending, the
+ // notification dialogs are run one after the other.
+
+ if (aRequestId != iCurrentRequest)
+ {
+ if (aRequestId == KPosNullQNRequestId)
+ {
+ return;
+ }
+ //Put this new Notification Request on the queue and then process
+ //it later from iRequestActiveObject(CLpdRequestAO class) RunL.
+ RPosRequestorStack* requestors = NULL;
+ TRAP_IGNORE(
+ SetCurrentRequestL(aRequestId);
+ // requestors is allocated in iRtorProcessor and ownership is finally
+ // transferred to iRequestActiveObject.
+ requestors = iRtorProcessor->RetrieveRequestorsL( *this );
+ // Enqueue the request to iRequestActiveObject
+ iRequestActiveObject->EnqueueRequestL(RequestSource(),
+ CancelReason(),
+ QueryTimeoutStrategy(),
+ requestors););
+ return;
+ }
+
+ iCancelInfo.iCancelled = ETrue;
+ iCancelInfo.iReason = CancelReason();
+ iCancelInfo.iDecision = QueryTimeoutStrategy();
+ iCancelInfo.iSource = RequestSource();
+
+ if (iCurrentRequestType == EQuery)
+ { // Verification was cancelled
+ __ASSERT_DEBUG( iVerifierQuery, HandleDebugAssertError() );
+ __ASSERT_DEBUG( !iNotifier, HandleDebugAssertError() );
+ iVerifierQuery->Cancel();
+ }
+ else
+ {
+ // It must be a notification then, this case is not probable but
+ // we can cancel the dialog if this would happen.
+ __ASSERT_DEBUG( iCurrentRequestType == ENotification,
+ HandleDebugAssertError() );
+ __ASSERT_DEBUG( !iVerifierQuery, HandleDebugAssertError() );
+ __ASSERT_DEBUG( iNotifier, HandleDebugAssertError() );
+ iNotifier->Cancel();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleAllRequestCancelled
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleAllRequestCancelled()
+ {
+ if (iCurrentRequest != KPosNullQNRequestId)
+ { // current request requires some specific behavior
+ HandleRequestCancelled(iCurrentRequest);
+ }
+ // Note that ScheduleRequest in the end of HandleRequestCancelled() allows
+ // current call chain run to completion and resources are released after
+ // that. Pending requests have been completed so they won't be processed.
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleVerificationResultL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleVerificationResultL(TInt aResultCode)
+ {
+ iVerifyResult = aResultCode;
+
+ LOCVERIFIERDLGDEBUG1( "CLpdVerifierPlugin::HandleVerificationResultL(%d)",
+ iVerifyResult );
+
+ switch (iVerifyResult)
+ {
+ case KErrNone: // fall through
+ case KErrAccessDenied:
+ {
+ // No need for rules now in 3.0
+ break;
+ }
+ case KErrTimedOut:
+ { // UI's internal timer expired
+ break;
+ }
+ case KErrCancel:
+ {
+ __ASSERT_DEBUG( iCancelInfo.iCancelled, HandleAssertErrorL() );
+ NotifyCancellationL(iCancelInfo.iSource, iCancelInfo.iReason,
+ iCancelInfo.iDecision);
+
+ return; // don't handle next req. yet
+ }
+ case KErrAbort: // This is used for emergency call support
+ {
+ CompleteAllRequests(iVerifyResult);
+ // ScheduleRequest() allows the current call chain
+ // run to completion and resources are released after that.
+ iRequestActiveObject->ScheduleRequest();
+ return;
+ }
+ default:
+ {
+ iEnv->HandleError(iVerifyResult);
+ break;
+ }
+ }
+
+ CompleteCurrentAndContinue(iVerifyResult); // this request was handled
+ }
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNotificationResultL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNotificationResultL(TInt aResultCode)
+ {
+
+ TLpdPeriodicReqInfo newReq(iCurrentRequest, -1);
+ TIdentityRelation<TLpdPeriodicReqInfo> matcher(
+ TLpdPeriodicReqInfo::MatchPrivacy);
+ TInt index = iPeriodicNotQue.Find(newReq, matcher);
+
+ // Remove if it was present in Que
+ if (index != KErrNotFound)
+ {
+ iPeriodicNotQue.Remove(index);
+ }
+ CompleteRequest(iCurrentRequest, aResultCode);
+ iCurrentRequest = KPosNullQNRequestId;
+
+ switch (aResultCode)
+ {
+ case KErrNone: // fall through
+ case KErrTimedOut: // fall through
+ {
+ break;
+ }
+ case KErrCancel:
+ {
+ break;
+ }
+ case KErrAbort: // This is used for emergency call support
+ {
+ CompleteAllRequests(aResultCode);
+ // ScheduleRequest() -> allows the current call chain
+ // run to completion and resources are released after that.
+ break;
+ }
+ default:
+ {
+ iEnv->HandleError(aResultCode);
+ break;
+ }
+ }
+
+ iRequestActiveObject->ScheduleRequest(); // handle next req.
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleLeave
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleLeave(TInt aError)
+ {
+ LOCVERIFIERDLGDEBUG1( "CLpdVerifierPlugin::HandleLeave(%d)", aError);
+ // In this case user needs feedback about the error situation:
+ iEnv->HandleError(aError);
+
+ // In case of leave current request is completed with
+ // iVerifyResult, but queue handling is still continued.
+ // iVerifyResult is better completion code for request than aError.
+ CompleteCurrentAndContinue(iVerifyResult);
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNextRequest
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNextRequest()
+ {
+ TRAPD( err, HandleNextRequestL() );
+ if (err)
+ {
+ // In case of leave current request is completed with
+ // error code, but queue handling is still continued.
+
+ // If we couldn't start handling the request it is
+ // better not to confuse user with an error note.
+
+ CompleteCurrentAndContinue(iVerifyResult);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNextRequestL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNextRequestL()
+ {
+
+ // It is better to free previous query resources here, because
+ // now all callback methods have finished (active object allowed
+ // run to completion)
+ this->FreeQueryResources();
+
+ // Read the next request:
+ RArray<TPosQNRequestId> requests;
+ CleanupClosePushL(requests);
+ GetRequestsL(requests);
+
+ if (requests.Count() == 0)
+ { // No more requests to handle
+ CleanupStack::PopAndDestroy(); // requests
+ // This is a very important step, it allows new requests
+ // to flow in ( see HandleNewRequestL() ):
+ delete iRequestActiveObject;
+ iRequestActiveObject = NULL;
+ return;
+ }
+ iCurrentRequest = requests[0];
+ CleanupStack::PopAndDestroy(); // requests
+ SetCurrentRequestL(iCurrentRequest);
+
+ // Check whether the request is coming from Uikon Server. If not reject this request.
+ if (!CheckClientSecureId(KUikonSrvSecureId))
+ {
+ CompleteCurrentAndContinue(KErrPermissionDenied);
+ return;
+ }
+
+ // Check the request type
+ iCurrentRequestType = RequestTypeL(iCurrentRequest);
+
+ if ((CheckRequestTypeL() == CPosRequestor::ERequestPeriodic)
+ && (iCurrentRequestType == ENotification))
+ iRtorProcessor->SetRequestType(KPeriodicRequest);
+ else
+ iRtorProcessor->SetRequestType(KNonPeriodicRequest);
+
+ iRtorProcessor->ReadRequestorsL(*this);
+
+ if (iCurrentRequestType == EQuery)
+ {
+ HandleNextVerificationL();
+ }
+ else if (iCurrentRequestType == ENotification)
+ {
+ HandleNextNotificationL();
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNextVerificationL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNextVerificationL()
+ {
+ __ASSERT_DEBUG( iCurrentRequest != KPosNullQNRequestId,
+ HandleAssertErrorL() );
+ __ASSERT_DEBUG( !iVerifierQuery, HandleAssertErrorL() );
+ TInt suplRequest;
+ if (CheckRequestTypeL() == CPosRequestor::ERequestPeriodic)
+ suplRequest = 1;
+ else
+ suplRequest = 0;
+
+ TPosRequestSource source(RequestSource());
+ if (source == EPosRequestSourceNotAvailable)
+ {
+ CompleteCurrentAndContinue(KErrNone);
+ }
+ else
+ {
+ if(suplRequest)
+ {
+ iPeriodicProcessor->SetRequestorIdL( CurrentRequest() );
+ iPeriodicProcessor->SetRequestTypeL(iCurrentRequestType);
+
+ CPosRequestor* req = NULL;
+ if( RequestorCountL() )
+ {
+ req = RequestorLC( 0 );
+ CleanupStack::Pop();
+ }
+ iPeriodicProcessor->SetRequestorL( req );
+
+ }
+
+ iVerifierQuery = CLpdVerifierQueryLauncher::NewL(*this);
+ TPosRequestDecision decision(QueryTimeoutStrategy());
+ // Note that item is left in cleanupstack until StartQuery():
+ if (suplRequest)
+ iVerifierQuery->PrepareSuplVerificationResourcesL();
+ else
+ iVerifierQuery->PrepareVerificationResourcesL(source, decision);
+
+ // Ownership of text is immediatelly transferred:
+ CLpdBaseModel* requestors = iRtorProcessor->RtorNamesForVerifNotifL(
+ iVerifierQuery->ListBoxL());
+ iVerifierQuery->SetQueryTextArray(requestors);
+
+ // Start the Verification query
+ StartQueryDialogL(iVerifierQuery, EVerificationRequest, decision);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNextNotificationL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNextNotificationL()
+ {
+ __ASSERT_DEBUG( iCurrentRequest != KPosNullQNRequestId,
+ HandleAssertErrorL() );
+
+ if (CheckRequestTypeL() == CPosRequestor::ERequestPeriodic)
+ HandleNextPeriodicNotificationL();
+ else
+ HandleNextNonPeriodicNotificationL();
+
+ }
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNextNonPeriodicNotificationL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNextNonPeriodicNotificationL()
+ {
+ __ASSERT_DEBUG( iCurrentRequest != KPosNullQNRequestId,
+ HandleAssertErrorL() );
+ __ASSERT_DEBUG( !iNotifier, HandleAssertErrorL() );
+
+ if (RequestSource() != EPosRequestSourceNetwork)
+ { // Notifications are supported only for network requests
+ User::Leave(KErrNotSupported);
+ }
+
+ TPosNotificationReason reason = NotificationReason();
+ switch (reason)
+ {
+ // Decision without user's consent:
+ case EPosDecisionByRequestSource:
+ // Policy conflict, network timeout occurred before user's
+ // response was received
+ {
+
+ TPosRequestDecision decision = LocationRequestDecision();
+ if(!iNotifier)
+ iNotifier = CLpdNotifierQueryLauncher::NewL(*this);
+ iNotifier->PrepareNotificationResourcesL(reason, decision);
+ CLpdBaseModel* requestors =
+ iRtorProcessor->RtorNamesForVerifNotifL(
+ iNotifier->ListBoxL());
+
+ iNotifier->SetQueryTextArray(requestors);
+
+ // Start the notification query
+ StartQueryDialogL(iNotifier, ENotification, decision);
+ break;
+ }
+ case EPosVerificationTimeout:
+ {
+ TPosRequestDecision decision = LocationRequestDecision();
+ if(!iNotifier)
+ iNotifier = CLpdNotifierQueryLauncher::NewL(*this);
+ iNotifier->PrepareNotificationResourcesL(reason, decision);
+ CLpdBaseModel* requestors =
+ iRtorProcessor->RtorNamesForVerifNotifL(
+ iNotifier->ListBoxL());
+ iNotifier->SetQueryTextArray(requestors);
+
+ // Start the notification query
+ StartQueryDialogL(iNotifier, ENotificationTimeout, decision);
+
+ break;
+ }
+ case EPosNotificationReasonNotAvailable: // fall through
+ default: // Future extensions -> EPosNotificationReasonNotAvailable
+ {
+ User::Leave(KErrNotSupported);
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleNextPeriodicNotificationL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleNextPeriodicNotificationL()
+ {
+ __ASSERT_DEBUG( iCurrentRequest != KPosNullQNRequestId,
+ HandleAssertErrorL() );
+
+ if (RequestSource() != EPosRequestSourceNetwork)
+ { // Notifications are supported only for network requests
+ User::Leave(KErrNotSupported);
+ }
+
+ TPosNotificationReason reason = NotificationReason();
+
+ switch (reason)
+ {
+ // Decision without user's consent:
+ case EPosDecisionByRequestSource:
+ // Policy conflict, network timeout occurred before user's
+ // response was received
+ {
+ iPeriodicProcessor->SetRequestorIdL( CurrentRequest() );
+ iPeriodicProcessor->SetRequestTypeL(iCurrentRequestType);
+ CPosRequestor* req = NULL;
+ if( RequestorCountL() )
+ {
+ req = RequestorLC( 0 );
+ CleanupStack::Pop();
+ }
+ iPeriodicProcessor->SetRequestorL( req );
+
+ TPosRequestDecision decision = LocationRequestDecision();
+
+ if(!iNotifier)
+ iNotifier = CLpdNotifierQueryLauncher::NewL(*this);
+
+ TInt64 sessionId = -1;
+ sessionId = iRtorProcessor->GetSessionId();
+ iPeriodicProcessor->SetSessionIdL(sessionId);
+
+ HBufC* requestorName = NULL;
+ if (iRtorProcessor->Requestors().Count() == 0)
+ {
+ requestorName = StringLoader::LoadL(R_LPD_UNKNOWN_REQUESTER);
+ }
+ else
+ {
+ const CPosRequestor& requestor =
+ *(iRtorProcessor->Requestors())[1];
+ iUtils = CLocRequestorUtilsResolver::NewL();
+ requestorName = iUtils->RequestorNameL(requestor);
+ if ((requestorName->Des()).CompareC(_L("Unknown")) == 0)
+ {
+ requestorName = NULL;
+ requestorName = StringLoader::LoadL(
+ R_LPD_UNKNOWN_REQUESTER);
+ }
+ delete iUtils;
+ iUtils = NULL;
+ }
+ iPeriodicProcessor->SetRequestorNameL(requestorName);
+
+ delete requestorName;
+ iNotifier->PrepareSuplNotificationResourcesL(reason);
+
+ HBufC* notifyMessage = HBufC::NewLC(KNotifyMessageLength);
+ TRAPD( err, iPeriodicProcessor->NotificationMessageTextL(notifyMessage));
+
+ if (err == KErrNotFound)
+ {
+ CleanupStack::PopAndDestroy(); // notifyMessage
+ CompleteCurrentAndContinue(err);
+ }
+ else
+ {
+ iNotifier->SetMessageQueryTextL(notifyMessage->Des(),
+ iPeriodicProcessor->LinkCallBack());
+
+ CleanupStack::PopAndDestroy(); // notifyMessage
+ // Start the notification query
+ StartQueryDialogL(iNotifier, ESuplPeriodicNotification,
+ decision);
+ }
+ break;
+ }
+ case EPosVerificationTimeout:
+ {
+ break;
+ }
+ case EPosNotificationReasonNotAvailable: // fall through
+ default: // Future extensions -> EPosNotificationReasonNotAvailable
+ {
+ User::Leave(KErrNotSupported);
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::NotifyCancellationL
+// Helper method
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::NotifyCancellationL(TPosRequestSource aSource,
+ TPosVerifyCancelReason aReason, TPosRequestDecision aDecision)
+ {
+ __ASSERT_DEBUG( iCurrentRequestType == EQuery, HandleAssertErrorL() );
+
+ if (aSource == EPosRequestSourceNetwork)
+ { // Notifications supported only for network-originated requests
+
+ switch (aReason)
+ {
+ case EPosCancelReasonTimeout:
+ {
+ __ASSERT_DEBUG( !iNotifier, HandleAssertErrorL() );
+ if(aDecision != EPosDecisionNotAvailable)
+ {
+ iNotifier = CLpdNotifierQueryLauncher::NewL( *this );
+ iNotifier->PrepareCancelNotifResourcesL( aDecision );
+ CLpdBaseModel* requestors =
+ iRtorProcessor->RtorNamesForVerifNotifL(
+ iNotifier->ListBoxL() );
+ iNotifier->SetQueryTextArray( requestors );
+
+ // Start the notification query
+ StartQueryDialogL( iNotifier,
+ ECancelNotification,
+ aDecision );
+
+ return;
+ }
+ break;
+ }
+ case EPosCancelReasonNotAvailable: // fall through
+ default: // future extensions -> EPosCancelReasonNotAvailable
+ {
+ break;
+ }
+ }
+ }
+
+ // If notification dialog was not launched, handle next request:
+ iRequestActiveObject->ScheduleRequest();
+
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::CompleteCurrentAndContinue
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::CompleteCurrentAndContinue(TInt aResultCode)
+ {
+ if (iCurrentRequest != KPosNullQNRequestId)
+ {
+ CompleteRequest(iCurrentRequest, aResultCode);
+ }
+ iCurrentRequest = KPosNullQNRequestId;
+
+ __ASSERT_DEBUG( iRequestActiveObject, HandleDebugAssertError() );
+ iRequestActiveObject->ScheduleRequest(); // handle next req.
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::FreeQueryResources
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::FreeQueryResources()
+ {
+ if(iPeriodicProcessor)
+ iPeriodicProcessor->ResetParameters();
+ iCurrentRequest = KPosNullQNRequestId;
+ delete iVerifierQuery;
+ iVerifierQuery = NULL;
+ iVerifyResult = KErrGeneral;
+ iCancelInfo.iCancelled = EFalse;
+ delete iNotifier;
+ iNotifier = NULL;
+ if (iRtorProcessor)
+ { // if already construction fails iRtorProcessor may
+ // be NULL, otherwise it points to an instance.
+ iRtorProcessor->ResetAndDestroyRequestors();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleAssertErrorL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleAssertErrorL() const
+ {
+#ifdef _DEBUG
+ User::Panic(KPanicText, KLpdErrGeneral);
+#else
+ User::Leave( KErrCorrupt );
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::HandleDebugAssertError
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::HandleDebugAssertError() const
+ {
+#ifdef _DEBUG
+ User::Panic(KPanicText, KLpdErrGeneral);
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::NotifyTimeoutL
+// Helper method
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::NotifyCancellationL(
+ TPosRequestSource aSource,
+ TPosVerifyCancelReason aReason,
+ TPosRequestDecision aDecision,
+ const RPosRequestorStack& aRequestors )
+ {
+ if ( aSource == EPosRequestSourceNetwork )
+ { // Notifications supported only for network-originated requests
+
+ switch ( aReason )
+ {
+ case EPosCancelReasonTimeout:
+ {
+ __ASSERT_DEBUG( !iNotifier, HandleAssertErrorL() );
+ if(aDecision != EPosDecisionNotAvailable)
+ {
+ iNotifier = CLpdNotifierQueryLauncher::NewL( *this );
+ iNotifier->PrepareCancelNotifResourcesL( aDecision );
+ iRtorProcessor->ReadRequestorsL(aRequestors);
+ CLpdBaseModel* requestors =
+ iRtorProcessor->RtorNamesForVerifNotifL(
+ iNotifier->ListBoxL() );
+ iNotifier->SetQueryTextArray( requestors );
+
+ // Start the notification query
+ StartQueryDialogL( iNotifier,
+ ECancelNotification,
+ aDecision );
+
+ return;
+ }
+ break;
+ }
+ case EPosCancelReasonNotAvailable: // fall through
+ default: // future extensions -> EPosCancelReasonNotAvailable
+ {
+ break;
+ }
+ }
+ }
+
+ // If notification dialog was not launched, handle next request:
+ iRequestActiveObject->ScheduleRequest();
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::StartQueryDialogL
+// Starts the Query dialog
+// @param aQueryDialog Query dialog that has to be started
+// @param aDialogType Dialog type
+// @param aDecision Decision Type
+// -----------------------------------------------------------------------------
+void CLpdVerifierPlugin::StartQueryDialogL(
+ CLpdQueryLauncherBase* aQueryDialog, TDialogType aDialogType,
+ TPosRequestDecision aDecision)
+ {
+ // Set the Command ID
+ TInt coverUiCmd = CoverUICommandL(aDialogType, aDecision);
+
+ aQueryDialog->SetCoverUICommand(coverUiCmd);
+ // Set the Requestor buffer
+ CBufFlat* reqBuffer = PackRequestorBufferL();
+ CleanupStack::PushL(reqBuffer);
+
+ TPtr8 reqBufferPtr(reqBuffer->Ptr(0));
+ aQueryDialog->SetRequestorBuffer(reqBufferPtr);
+
+ if (aDialogType == ESuplPeriodicNotification)
+ aQueryDialog->StartSuplPeriodicQueryL();
+ else
+ aQueryDialog->StartQueryL();
+
+ CleanupStack::PopAndDestroy(reqBuffer);
+
+
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::PackRequestorBufferL
+// Packs the Requestor buffer to send across to Cover UI. The
+// ownership of the buffer is transferred back to the callee
+// @return CBufFlat* Flat buffer containing the list of requestors
+// -----------------------------------------------------------------------------
+//
+CBufFlat* CLpdVerifierPlugin::PackRequestorBufferL()
+ {
+ // Construct the conversion buffers and the package buffer
+ CBufFlat* requestorBuffer = CBufFlat::NewL(KReqBufferIncrSize);
+ CleanupStack::PushL(requestorBuffer);
+
+ // Opening a Write stream to assist in packing data onto CBufFlat
+ RBufWriteStream writeStream;
+ writeStream.Open(*requestorBuffer);
+ CleanupClosePushL(writeStream);
+
+ // Obtain the list of requestors from which the individual requestor
+ // Ids can be obtained
+ const RPointerArray<CPosRequestor>& requestors =
+ iRtorProcessor->Requestors();
+
+ // The buffer is packed according to the below mentioned
+ // format.
+ //
+ // | Count | Length(1) | String(1) | ..... | Length( Count ) | String( Count ) |
+ //
+ // where,
+ // Count - ( 4 bytes ) - The number of requestor strings.
+ // Length(n) - ( 4 bytes ) - Length of the nth requestor string.
+ // String(n) - ( Length(n) * 2 bytes ) - String for the nth requestor.
+ //
+ // Each entry is packed one after another without any delimters between them
+ //
+
+ // Packing the count
+ writeStream.WriteInt32L(requestors.Count());
+
+ for (TInt i = 0; i < requestors.Count(); i++)
+ {
+ const CPosRequestor& req = *(requestors[i]);
+
+ // Obtain the Requestor Id string
+ TPtrC reqStr = req.RequestorIdString();
+
+ // We need a 16 bit buffer for converting. Since the requestor strings that
+ // need to be packed have to always be of the UCS-2 ( UNICODE ) format.
+ // The buffer would be allocated just before copying the requestor content
+ HBufC16* conversionBuf = NULL;
+ TPtr16 conBufPtr(0, 0);
+
+ // If the string is a phone number then it needs to be grouped and the
+ // converted to a UNICODE string. If not, then simpy convert it to
+ // a UNICODE string
+ if (CPosRequestor::EIdFormatPhoneNumber == req.RequestorIdFormat())
+ {
+ // Creating the Phone number formatter for grouping
+ CLocPhoneNumberFormat* formatter = CLocPhoneNumberFormat::NewL();
+ CleanupStack::PushL(formatter);
+
+ HBufC* groupedName = NULL;
+ TRAPD( error, groupedName = formatter->PhoneNumberGroupL( reqStr ));
+ if (error || !groupedName)
+ {
+ // If there was a Leave in the grouping function or the
+ // grouping failed then pack the original name
+
+ // Allocate the conversion buffer and copy the Requestor string
+ conversionBuf = HBufC16::NewL(reqStr.Length());
+ conBufPtr.Set(conversionBuf->Des());
+
+ // Copy the original string to the conversion buffer
+ conBufPtr.Copy(reqStr);
+ }
+ else
+ {
+ // Take ownership of the grouped phone number buffer and
+ // copy it to the conversion buffer
+ CleanupStack::PushL(groupedName);
+
+ TPtr groupedNamePtr = groupedName->Des();
+
+ // Allocate the conversion buffer and copy the Requestor string
+ conversionBuf = HBufC16::NewL(groupedNamePtr.Length());
+ conBufPtr.Set(conversionBuf->Des());
+
+ // Copy the grouped string to the conversion buffer
+ conBufPtr.Copy(groupedNamePtr);
+
+ CleanupStack::PopAndDestroy(groupedName);
+ }
+
+ CleanupStack::PopAndDestroy(formatter);
+ }
+ else
+ {
+ // Copy the Requestor ID string
+
+ // Allocate the conversion buffer and copy the Requestor string
+ conversionBuf = HBufC16::NewL(reqStr.Length());
+ conBufPtr.Set(conversionBuf->Des());
+
+ // Copy the original string to the conversion buffer
+ conBufPtr.Copy(reqStr);
+ }
+
+ // Push the Conversion buffer to the CleanupStack
+ CleanupStack::PushL(conversionBuf);
+
+ // The conversion buffer now contains the string in the UNICODE
+ // format. First pack the length of the string and then the
+ // actual string itself
+ writeStream.WriteInt32L(conBufPtr.Length());
+
+ TUint8* buffer = (TUint8*) (conBufPtr.Ptr());
+ writeStream.WriteL(buffer, conBufPtr.Size());
+
+ // Destroying the Conversion buffer before it goes out of scope
+ CleanupStack::PopAndDestroy(conversionBuf);
+ }
+
+ // flush stream data to our buffer
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(&writeStream);
+
+ // The ownership of the requestor buffer should be transferred to the callee
+ CleanupStack::Pop(requestorBuffer);
+
+ return requestorBuffer;
+ }
+
+// -----------------------------------------------------------------------------
+// Determines the Cover UI command corresponding to a paricular
+// request
+// @param TRequestType Request Type
+// @param TPosRequestDecision Decision Type
+// @return TInt Cover UI Command ID.
+// -----------------------------------------------------------------------------
+//
+TInt CLpdVerifierPlugin::CoverUICommandL(TDialogType aRequestType,
+ TPosRequestDecision aDecision)
+ {
+ TInt result = 0;
+
+ if (EVerificationRequest == aRequestType)
+ {
+ switch (aDecision)
+ {
+ case EPosDecisionAccepted:
+ {
+ result = ECmdDefaultAccept;
+ break;
+ }
+ case EPosDecisionRejected:
+ {
+ result = ECmdDefaultReject;
+ break;
+ }
+ default:
+ {
+ result = ECmdDefaultNone;
+ break;
+ }
+ }
+ }
+ else if ((ENotification == aRequestType) || (ESuplPeriodicNotification
+ == aRequestType))
+ {
+ result = ECmdNotifyAccept;
+ }
+ else if (ENotificationTimeout == aRequestType)
+ {
+ switch (aDecision)
+ {
+ case EPosDecisionAccepted:
+ {
+ result = ECmdNotifyRejectFailure;
+ break;
+ }
+ case EPosDecisionRejected:
+ {
+ result = ECmdNotifyAcceptFailure;
+ break;
+ }
+ default:
+ {
+ User::Leave(KErrNotFound);
+ break;
+ }
+ }
+ }
+ else if (ECancelNotification == aRequestType)
+ {
+ switch (aDecision)
+ {
+ case EPosDecisionAccepted:
+ {
+ result = ECmdNotifyAcceptTimeout;
+ break;
+ }
+ case EPosDecisionRejected:
+ {
+ result = ECmdNotifyRejectTimeout;
+ break;
+ }
+ default:
+ {
+ User::Leave(KErrNotFound);
+ break;
+ }
+ }
+ }
+ else
+ {
+ User::Leave(KErrNotFound);
+ }
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::CheckRequestTypeL
+// Checks the type of request and helps to know
+// if a given request is of SUPL periodic type
+// @param aCurrentRequest request id
+// @return TRequestType type of request enum
+// -----------------------------------------------------------------------------
+CPosRequestor::TRequestType CLpdVerifierPlugin::CheckRequestTypeL()
+ {
+ CPosRequestor::TRequestType reqType = CPosRequestor::ENetworkTypeUnknown;
+ if (RequestorCountL() > 0)
+ {
+ CPosRequestor* requestor = RequestorLC(0);
+ reqType = requestor->RequestType();
+ CleanupStack::PopAndDestroy(requestor);
+ }
+ return reqType;
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::GetSessionIdL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::GetSessionIdL( TInt64& aSessionId )
+ {
+ CPosRequestor* curRequestor = RequestorLC( 0 );
+ TInt length = curRequestor->RequestorIdString().Length();
+ TPtrC reqString(curRequestor->RequestorIdString().Mid( length - 3 ));
+ TLex temp(reqString);
+ temp.Val(aSessionId);
+ CleanupStack::PopAndDestroy( curRequestor );
+ }
+
+// -----------------------------------------------------------------------------
+// CLpdVerifierPlugin::UpdateCurrentNotifierL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLpdVerifierPlugin::UpdateCurrentNotifierL()
+ {
+ // Confirm if the current request type is Notification before
+ // processing/updating.
+
+ __ASSERT_DEBUG( iCurrentRequestType == ENotification,
+ HandleDebugAssertError() );
+ __ASSERT_DEBUG( iPeriodicProcessor, HandleDebugAssertError() );
+ if(iNotifier)
+ iNotifier->CancelQuietly();
+ HandleNextPeriodicNotificationL();
+
+ }
+
+// End of File