Creating a Privacy Verification Notifier

To use the LBS Privacy Notifiers for privacy verification and privacy notification a licensee must implement a Privacy Verification Notifier that extends from the Extended Notifier Framework base class MEikSrvNotifierBase2. The licensee must override the asynchronous MEikSrvNotifierBase2::StartL() method so that the LBS subsystem can receive a privacy response from the user via the notifier.

This topic describes how to implement a Privacy Verification Notifier. The notifier is used to handle privacy verification requests.

A dialog is shown to the user when verification of a privacy request is required. The example shown here uses a CEikDialog derived class, although licensees will most probably want to use a dialog class specific to their own UI framework. Implementation of the notifier can be described in the following steps:

  • Define a notifier that derives from the Extended Notifier Framework base class MEikSrvNotifierBase2.

  • Define a dialog class that derives from CEikDialog (or some licensee UI framework-specific subclass).

  • Override the necessary virtual methods of the licensee notifier and dialog to handle privacy requests and send the appropriate response when the user dismisses the dialog.

Defining the Privacy Verification Notifier

The code below shows a definition of a Privacy Verification Notifier class.

The notifier owns a CMyLBSPrivacyVerifierDialog dialog class to show details of the privacy request to the end user and to obtain the response.

/*
============================================================================
 Name		 : MyLBSPrivacyVerifier.h
 Description : This file defines a LBS Privacy Verification Notifier
============================================================================
*/

#ifndef __MYLBSPRIVACYVERIFIER_H__
#define __MYLBSPRIVACYVERIFIER_H__

// Default location for dialog GUI resources
#define VERIFY_RESOURCE_PATH    "\\private\\10003a4a\\"

// Compiled dialog resource file name
#define VERIFY_RESOURCE 		"MyLBSPrivacyDialogs.rsc"

//  Include Files
#include <e32base.h>
#include <eiknotapi.h>
#include <eikdialg.h>
#include "lbsprivacyextnotifiers.h" // Defines privacy data types
#include "MyLBSNotifiersChannel.h" // Defines notifier channel

// Dialog forward declaration for notifier
class CMyLBSPrivacyVerifierDialog;

//  Privacy verification notifier class definition
class CMyLBSPrivacyVerifier : public CBase, public MEikSrvNotifierBase2
  {
public:	
  static CMyLBSPrivacyVerifier* NewL();
  ~CMyLBSPrivacyVerifier();
		
  // Called when the dialog is hidden
  void DialogDismissed();

private: // From MEikSrvNotifierBase2

  // Asynchronous StartL is used for privacy verification
  // a response is required
  void StartL(const TDesC8& aBuffer, TInt aReplySlot,
              const RMessagePtr2& aMessage); 
	
  // Synchronous StartL is not used for privacy verification
  TPtrC8 StartL(const TDesC8& aBuffer);
	
  // Not implemented for LBS privacy notifiers
  TPtrC8 UpdateL(const TDesC8& aBuffer);
	
  TNotifierInfo RegisterL();
  TNotifierInfo Info() const;
  void Cancel();
  void Release();
	
  // Set the response parameters based on the user response
  void SetResponseParams(TLbsPrivacyResponseParams params);
	

private:
  CMyLBSPrivacyVerifier();
  void ConstructL();

private:
  // Data members
  TNotifierInfo iInfo;
  RMessagePtr2 iMessage;
  TInt iReplySlot;
		
  // From lbsprivacyextnotifiers.h - request parameters
  TLbsPrivacyNotifierParams iRequestParams;
		
  // From lbsprivacyextnotifiers.h - response parameters
  TLbsPrivacyResponseParams iResponseParams;

  // Verification Dialog
  CMyLBSPrivacyVerifierDialog* iDlg;
  };

#endif  // __MYLBSPRIVACYNOTIFIER_H__

Defining the Privacy Verification Dialog

The following is the definition of the dialog used by the example Privacy Verification Notifier:

/*
============================================================================
 Name		: MyLBSPrivacyVerifier.cpp
 Description : Source for LBS privacy verification notifier and dialog
============================================================================
*/

// System headers
#include <eikdialg.h>
#include <eikmfne.h>
#include <eikenv.h>
#include <bautils.h>
#include <eikappui.h>
#include <e32cmn.h>

// Console for debugging
#include <e32cons.h>		

// LBS headers
#include <lbsprivacyextnotifiers.h>

// project headers
#include <MyLBSPrivacyDialogs.rsg>
#include "MyLBSPrivacyVerifier.hrh"
#include "MyLBSDialogs.hrh"
#include "MyLBSPrivacyVerifier.h"


/* CMyLBSPrivacyVerifierDialog
   The resource for this dialog defines it as a sleeping dialog
   Resources are allocated when the owning notifier is created by ECom
*/

class CMyLBSPrivacyVerifierDialog : public CEikDialog
  {
public:
  static CMyLBSPrivacyVerifierDialog* NewLD(
                               CMyLBSPrivacyVerifier* aNotifier,
                               TLbsPrivacyResponseParams& aResponseParams);
  ~CMyLBSPrivacyVerifierDialog();

  void ShowDialog(TLbsExternalRequestInfo& aInfo);
  void HideDialog();

public: // from CEikDialog
  TBool OkToExitL(TInt aButtonId);
  void PreLayoutDynInitL();

private:
  CMyLBSPrivacyVerifierDialog(CMyLBSPrivacyVerifier* aNotifier,
                              TLbsPrivacyResponseParams& aResponseParams);
  void LoadResourceL();
  void FreeResource();
  void ConstructL();

private:

  // The notifier that calls this dialog
  CMyLBSPrivacyVerifier* iNotifier;
	
  // Library resource containing dialog resources
  TInt  iResourceFile;
	
  // The privacy requester info - contains requester id and name
  TLbsExternalRequestInfo iInfo;

  // The privacy response parameters reference
  // to iResponseParams in parent notifier
  TLbsPrivacyResponseParams& iResponseParams;
	 };

The dialog contains a CMyLBSPrivacyVerifier pointer through which it can set the privacy response chosen by the user.

This example defines a simple dialog resource file MyLbsPrivacyDialogs.rsg. The source of this file contains definitions for a simple dialog that shows the client name of the user making the privacy request and Accept and Reject buttons to allow the user to accept or reject the request.

// MyLBSPrivacyVerifierDialog.RSS

#include <eikon.rh>
#include <eikon.rsg>
#include <techviewctl.rh>
#include <eikcoctl.rsg>
#include "MyLBSDialogs.hrh"

NAME PRVC

RESOURCE RSS_SIGNATURE { }

RESOURCE TBUF { buf=""; }

RESOURCE DLG_BUTTONS r_privacy_request_buttons
{
buttons = 
	{
	DLG_BUTTON
		{
		id = EPrivacyRequestAccept;
		button = CMBUT {txt = "Accept";};
		hotkey='1';
		},
	DLG_BUTTON
		{
		id = EPrivacyRequestReject;
		button = CMBUT {txt = "Reject";};
		hotkey='2';
		}
	};
}


RESOURCE DIALOG r_lbs_verify_dialog
	{
	title = "Privacy Verification Dialog";
	flags = EEikDialogFlagNotifyEsc;
	buttons = r_privacy_request_buttons;
	items = 
		{
		DLG_LINE
		    {
		    type = EEikCtLabel;
		    control = LABEL
		    	{
		    	standard_font = EEikLabelFontAnnotation;
		    	txt = "Location Request received from :";
		    	};
		    },
		DLG_LINE
		    {
		    type = EEikCtEdwin;
		    id = EPrivacyClientName;
		    control = EDWIN
		    	{
		    	width = 10;
		    	maxlength = 25;
		    	};
		    }
		};
	}

KScreenOutputChannel is a common channel used by both a Privacy Verification Notifier and a Location Notification Notifier. The real value of the channel is a licensee-specific value.

#ifndef __MYLBSNOTIFIERSCHANNEL_H_
#define __MYLBSNOTIFIERSCHANNEL_H_

const TUid KScreenOutputChannel={0x1000ABEF};

#endif /*MYLBSNOTIFIERSCHANNEL_H_*/

Creating the notifier

The most important thing to consider when creating a notifier object is if the dialog resources should also be created at the same time.

The ECOM framework calls the notifier's NewL() when the notifier server starts up. Privacy requests and location requests may need to be handled in low memory conditions (where licensees and operators need to support emergency location requests). If this is the case it is prudent to use sleeping dialogs which are created in the notifier's ConstructL(). All resources for the dialog are allocated when the notifier is loaded by ECOM and showing a dialog should not fail if there are low-memory conditions at runtime when an emergency location request is received.

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

// Construct the dialog - it is a sleeping dialog 
// i.e. resources are allocated on construction
// This is a good idea for LBS privacy requests which must be handled
// in low memory conditions
void CMyLBSPrivacyVerifier::ConstructL()
  {	
  iDlg = CMyLBSPrivacyVerifierDialog::NewLD(this, iResponseParams);
  }

Registering the notifier

MEikSrvNotifierBase2::RegisterL() and MEikSrvNotifierBase2::Info() are standard notifier methods that can be implemented as shown below:

// Called by notifier framework once to register the notifier with ECOM
MEikSrvNotifierBase2::TNotifierInfo CMyLBSPrivacyVerifier::RegisterL()
  {
  iInfo.iUid = KLbsExtLocationRequestVerifyUid;
  iInfo.iChannel = KScreenOutputChannel;

  // High priority privacy request
  iInfo.iPriority = ENotifierPriorityVHigh;
  return iInfo;
  }

MEikSrvNotifierBase2::TNotifierInfo CMyLBSPrivacyVerifier::Info() const
  {
  return iInfo;
  }
Note: The value KLbsExtLocationRequestVerifyUid as defined in lbsextprivacynotifiers.h must be used for the notifier registration. The choice of notifier priority is a licensee decision, but a high priority is recommended because a user response is required.

Starting the notifier

A Privacy Verification Notifier must implement the asynchronous form of MEikSrvNortifierBase2::StartL(). The code example below shows how to do this. The LBS subsystem sends a TLbsPrivacyNotifierParamsPckg object to the notifier from which the TLbsExternalRequestInfo can be extracted.

// Asynchronous StartL is used for privacy verification because a response is required
void CMyLBSPrivacyVerifier::StartL(const TDesC8& aBuffer,
                                   TInt aReplySlot,
                                   const RMessagePtr2& aMessage)
  {
  // Copy aMessage and aReplySlot to reply to the request at a later time
  iMessage = aMessage;
  iReplySlot = aReplySlot;
	
  TBuf8<KLbsMaxClientNameSize> clientName;
  TBuf8<KLbsMaxRequesterIdSize> requesterId;
	
  TLbsPrivacyNotifierParamsPckg pckg;
  pckg.Copy(aBuffer);
  TLbsPrivacyNotifierParams params = pckg();
  TLbsExternalRequestInfo info;
  params.GetRequesterInfo(info);
	
  // Show the dialog with the requester details
  iDlg->ShowDialog(info);
  }
Note: A Privacy Verification Notifier need only implement an empty implementation of the synchronous MEikSrvNotifierBase2::StartL() method.

Getting the privacy response parameters

The example notifier has a method called DialogDismissed() which is called by the verification dialog when it is closed (either by pressing Accept or Cancel). The method implementation below shows how to package up the privacy response into a TLbsPrivacyReponseParamsPckg, complete the message and cancel the notifier.

// Called when dialog is dismissed
void CMyLBSPrivacyVerifier::DialogDismissed()
  {
  // Set the response on the basis of the response params
  if (!iMessage.IsNull())
    {
    // The dialog has already updated iResponseParams by reference
    // Create package buf to send parameters to the calling client
    TLbsPrivacyResponseParamsPckg pckg(iResponseParams);
    iMessage.WriteL(iReplySlot, pckg);
    iMessage.Complete(KErrNone);

    // Cancel the notifier
    iManager->CancelNotifier(KLbsExtLocationRequestVerifyUid);
		  }
  }

Cancelling the notifier

The LBS subsystem has a timeout for Privacy Notifiers that calls the MEikSrvNotifierBase2::Cancel() method.

// Called to cancel the notification (for example for a request timeout)
// The LBS subsystem sets the timeout for privacy notifiers
void CMyLBSPrivacyVerifier::Cancel()
  {
  if (!iMessage.IsNull())
    {
		  iMessage.Complete(KErrCancel);
		  }
  iDlg->HideDialog();
  }

Releasing the notifier

The ECOM release method just calls delete on the notifier.

// Just delete the notifier
void CMyLBSPrivacyVerifier::Release()
  {
  delete this;
  }

Notifier destructor

The destructor method just deletes the dialog object that was created in the notifier's ConstructL().

CMyLBSPrivacyVerifier::~CMyLBSPrivacyVerifier()
  {
  if (iDlg)
    {
    // Delete the dialog
    delete iDlg;
    }
  }

Constructing the dialog

These methods show how the dialog is constructed. A reference to the response parameters object owned by the parent notifier is passed by reference in the NewLD() method. This is written to when the user chooses to accept or reject the privacy request.

// Static function to create new dialog
// Response parameters passed by reference
// They are written when the dialog closes
CMyLBSPrivacyVerifierDialog* CMyLBSPrivacyVerifierDialog::NewLD(
                                CMyLBSPrivacyVerifier* aNotifier,
                                TLbsPrivacyResponseParams& aResponseParams)
  {
  CMyLBSPrivacyVerifierDialog* self
= new (ELeave) CMyLBSPrivacyVerifierDialog(aNotifier, aResponseParams);

  CleanupStack::PushL(self);
  self->ConstructL();
  CleanupStack::Pop(self);
  return self;
  }

// Private dialog constructor 
// Set the notifier to be the observer 
// and pass a reference to response parameters
CMyLBSPrivacyVerifierDialog::CMyLBSPrivacyVerifierDialog(
CMyLBSPrivacyVerifier* aNotifier, 
TLbsPrivacyResponseParams& aResponseParams) : 
iNotifier(aNotifier), iResponseParams(aResponseParams)
  {
  }

// Second stage constructor - load dialog resources
void CMyLBSPrivacyVerifierDialog::ConstructL()
  {
  LoadResourceL();	
  }

Loading dialog resources

For the example shown, the dialog resources are loaded when it is constructed (a sleeping dialog). This is a good design decision for dialogs that must be shown in low memory conditions, which is the case for the LBS dialogs that must notify of emergency location requests.

// Load resources for the dialog
void CMyLBSPrivacyVerifierDialog::LoadResourceL()
  {
	
  // Notifiers can be loaded from ROM or RAM
  // resource location is not hard-coded
  TFileName fileName;
  Dll::FileName(fileName);
  fileName.SetLength(KMaxDriveName);

  // force arg evaluation before calling _LIT
  #define _LIT1(k,s) _LIT(k,s) 
        
  // Values defined in MyLBSPrivacyVerifier.h
  // Dialog resources
  _LIT1(KRscFile, VERIFY_RESOURCE);
  _LIT1(KRscDir,  VERIFY_RESOURCE_PATH);
   
  fileName+=KRscDir;
  fileName+=KRscFile;

  // Load the dialog resources
  iEikonEnv = CEikonEnv::Static();
  BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(),fileName);
		
  TInt offset = iEikonEnv->AddLibraryL(&fileName);
  TRAPD(err, ConstructSleepingDialogL(R_LBS_VERIFY_DIALOG));
  iEikonEnv->DeleteResourceFile(offset);
  User::LeaveIfError(err);
  }

Showing the dialog

The method ShowDialog() is called by the notifier when it is started by a call to MEikSrvNotifierBase2::StartL(). In this example, all dialog resources were allocated at start-up so it is only necessary to show it.

void CMyLBSPrivacyVerifierDialog::ShowDialog(TLbsExternalRequestInfo& aInfo)
  {
  iInfo = aInfo;
  RouseSleepingDialog();
  }

The dialog method CEikDialog::PreLayoutDynInitL() is implemented to show the client name from TLbsExternalRequestInfo before the dialog is shown to the user. This method could also show the other data fields held in TLbsExternalRequestInfo.

// Populate the privacy verification dialog with the user identity
void CMyLBSPrivacyVerifierDialog::PreLayoutDynInitL()
  {
  TBuf8<KLbsMaxClientNameSize> clientName;
  TBuf8<KLbsMaxRequesterIdSize> requesterId;
  TBuf8<KLbsMaxClientExternalIdSize> externalId;
	
  iInfo.GetClientName(clientName);
  iInfo.GetRequesterId(requesterId);
  iInfo.GetClientExternalId(externalId);
	
  // Show the client name
  // Expand() only works for converting from ASCII
  // encoded buffer to Unicode
  // You may need to use CCnvCharacterSetConverter in your implementation

  CEikEdwin* edwin = STATIC_CAST(CEikEdwin*, 
                                 this->Control(EPrivacyClientName));
  edwin ->SetTextL(&clientName.Expand());
  edwin->SetReadOnly(ETrue);
	
  // Could also show the requesterId and externalId in the dialog...
  }

Making a privacy response

The dialog's CEikDialog::OkToExitL() method is called when the user selects Accept or Cancel. This method is implemented to set the TLbsPrivacyResponseParameters in the parent notifier with the user response, which is either to accept or reject the privacy request.

// From CEikDialog - called when a dialog button is pressed
TBool CMyLBSPrivacyVerifierDialog::OkToExitL(TInt aButtonId)
  {
  // Set the notifier response parameters based on user response
  // Member variable iResponse is reference
  // to notifier TLbsPrivacyResponseParams
	
  // Get the value of the pressed button
  if (aButtonId == EPrivacyRequestAccept)
    {
    iResponseParams.SetResponseType(EResponseAccepted);
    }
  else // Privacy request rejected 
    {
    iResponseParams.SetResponseType(EResponseRejected);
    }

  // Inform the notifier that this dialog is exiting
  // so that it can inform the notifier manager
  iNotifier->DialogDismissed();
  return ETrue;
  }

Hiding the dialog and freeing resources

The dialog's HideDialog() method is called by the notifier when LBS cancels the notifier, for example if a timeout occurs or another privacy request is sent (a new privacy request cancels any outstanding privacy request). In this example, the dialog resources are not freed because the dialog is a sleeping dialog.

// Hide the dialog and report to the notifier
void CMyLBSPrivacyVerifierDialog::HideDialog()
  {
  // Using a sleeping dialog
  ExitSleepingDialog();
  iNotifier->DialogDismissed();
  }

// Destructor frees dialog resources
CMyLBSPrivacyVerifierDialog::~CMyLBSPrivacyVerifierDialog()
  {
  iEikonEnv->EikAppUi()->RemoveFromStack(this);
  FreeResource();
  }

// Free dialog resources
void CMyLBSPrivacyVerifierDialog::FreeResource()
  {
  if (iResourceFile)
    {
		  CEikonEnv::Static()->RemoveLibrary(iResourceFile);
		  iResourceFile = 0;
    }
  }