--- a/Symbian3/PDK/Source/GUID-43080A86-72D3-5422-953E-A5EF79961D7B.dita Tue Mar 30 11:42:04 2010 +0100
+++ b/Symbian3/PDK/Source/GUID-43080A86-72D3-5422-953E-A5EF79961D7B.dita Tue Mar 30 11:56:28 2010 +0100
@@ -1,350 +1,350 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
-<!-- This component and the accompanying materials are made available under the terms of the License
-"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:
--->
-<!DOCTYPE concept
- PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
-<concept id="GUID-43080A86-72D3-5422-953E-A5EF79961D7B" xml:lang="en"><title>Writing
-a UPS Policy Evaluator</title><prolog><metadata><keywords/></metadata></prolog><conbody>
-<section id="GUID-56EDF170-1A32-4275-8799-99D13C485E1E"><title>Introduction</title> <p>Policy Evaluators are ECOM plug-ins.
-They allow security decisions to be specific to the data on which the service
-acts instead of simply granting full access to the service, for example "Allow
-application X to send SMS messages to 01234567". This is supported through
-the fingerprint functionality. They allow a security decision to be specific
-to an individual script executing within a scripting host. This is supported
-through the client entity field. And they allow a prompt to be displayed even
-if the user selected "Always" or "Never". This could be based on a usage threshold
-or simply as additional confirmation if the user selected "Never". This is
-supported through the force prompt functionality. </p> <p> <b>Note</b>: when
-a user selects “Never” or “Always”, the UPS creates a record in a decision
-database. This record identifies the system server UID, service UID, client
-SID, client entity name (name of an entity running within a client process,
-for example, a script identifier) and a "fingerprint" for a given decision. </p> <p>The
-purpose of a Policy Evaluator is to allow device creators to optionally customise
-the behaviour of the UPS at run-time. Policy Evaluators may: </p> <ul>
-<li id="GUID-1D5DD614-02E3-56AA-A0A6-A694E2311A0E"><p>Allow security decisions
-to be specific to the data on which the service acts instead of simply granting
-full access to the service, for example "Allow application X to send SMS messages
-to 01234567". This is supported via the fingerprint functionality. </p> </li>
-<li id="GUID-5B5E3EB4-5C93-5E4E-BB6E-39F889AD3610"><p>Allow a security decision
-to be specific to an individual script executing within a scripting host.
-This is supported via the client entity field. </p> </li>
-<li id="GUID-8B26DA57-A9DF-5D99-A259-2E6DF7C4DCCE"><p>Allow a prompt to be
-displayed even if the user selected "Always" or "Never". This could be based
-on a usage threshold or simply as additional confirmation if the user selected
-"Never". This is supported via the force prompt functionality. </p> </li>
-</ul> </section>
-<section id="GUID-CCBB139D-0F1C-4AD4-B2F2-062CF660A0DE"><title>Procedure</title> <p>Writing policy evaluator includes the
-following: </p> <ol id="GUID-F50174F6-3619-545A-8844-D4DA64B1B339">
-<li id="GUID-246EF2AB-23D9-5B1B-BC4C-8CCFB545C307"><p>Generating fingerprints </p> </li>
-<li id="GUID-4427FF70-9461-566A-8567-FC6EEF879475"><p>Forcing prompts </p> </li>
-<li id="GUID-703D9B83-78A0-5EA6-8D1C-685D2BC847EA"><p>Defining default policy
-evaluator </p> </li>
-</ol> <p>Policy evaluators implement the <codeph>CPolicyEvaluator</codeph> interface. </p> <p><b>Generating
-fingerprints</b> </p> <p>The key task of the policy evaluator is to generate
-fingerprints. A fingerprint is a collection of data describing the service
-being requested. The fingerprint usually includes the <codeph>destination</codeph> string,
-for example a telephone number, supplied by the service that is matched to
-the <codeph>destination</codeph> string of a policy in the policy file. </p> <p>The
-policy evaluator must implement the <codeph>GenerateFingerprints()</codeph> function,
-which is a pure virtual function, declared in the <xref href="GUID-FDE91CAC-1588-3EED-B509-08168F4B881B.dita"><apiname>CPolicyEvaluator</apiname></xref> base
-class. The function is asynchronous to allow the implementation to call other
-server processes. </p> <p>The following table describes the parameters for
-the <codeph>GenerateFingerprints()</codeph> function: </p> <table id="GUID-963D89B8-EB90-5668-8A08-588EF1E94C43">
-<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
-<thead>
-<row>
-<entry>Parameter</entry>
-<entry>Description</entry>
-</row>
-</thead>
-<tbody>
-<row>
-<entry><p> <codeph>aRequest</codeph> </p> </entry>
-<entry><p>Data that the system server provides to the UPS, including the ClientSid,
-ServerSid and ServiceId. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aPolicy</codeph> </p> </entry>
-<entry><p>Details of the policy for the service. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aFingerprints</codeph> </p> </entry>
-<entry><p>Array of fingerprints. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aClientEntity</codeph> </p> </entry>
-<entry><p>Details of client entity (will be null if the client process is
-not an execution host or the policy evaluator does not support client entities). </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aDialogCreatorParams</codeph> </p> </entry>
-<entry><p>Opaque data, which can be any other information for use in the fingerprint
-or to be displayed in the dialog. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aStatus</codeph> </p> </entry>
-<entry><p>The request status used to contain completion information for the
-function. </p> </entry>
-</row>
-</tbody>
-</tgroup>
-</table> <p>The following code fragment is a sample implementation of the <codeph>GenerateFingerprints()</codeph> function. </p> <codeblock id="GUID-B8555FDF-8BDD-5D22-AA20-AA9A4B35148A" xml:space="preserve">void CRefPolicyEvaluator::GenerateFingerprints(
- const CPromptRequest& aRequest, const CPolicy& aPolicy,
- RPointerArray<CFingerprint>& aFingerprints, const CClientEntity*& aClientEntity,
- const TAny*& aDialogCreatorParams, TRequestStatus& aStatus)
- {
- iRequest = &aRequest;
- iPolicy = &aPolicy;
- iFingerprints = &aFingerprints;
-
- // This OUT parameter *could* be set to point to data structure
- // owned by this policy evaluator that is read by the dialog-creator.
- aDialogCreatorParams = 0;
-
- // The client entity field only needs to be set if the policy evaluator
- // is designed to identify scripts/non-native applications being executed
- // by the client application.
- aClientEntity = 0;
-
- iClientStatus = &aStatus;
- aStatus = KRequestPending;
-
- // Kick off policy evaluator state machine
- iStatus = KRequestPending;
- TRequestStatus* status = &iStatus;
- SetActive();
- User::RequestComplete(status, KErrNone);
- }
-</codeblock> <p> <codeph>RunL()</codeph> is called when the request completes.
-The fingerprint is created and appended to the fingerprint array in <codeph>RunL()</codeph>.
-The following example shows a hash of a destination being created for a fingerprint
-as well as an empty fingerprint for decisions that apply to all destinations. </p> <codeblock id="GUID-EB57F6E0-C3B2-5CDC-B9FF-A570B73B4C74" xml:space="preserve">void CRefPolicyEvaluator::RunL()
- {
- // Create most specific hash first i.e. HASH(destination)
- // Information from the opaque data supplied by the system server
- // may also be used.
- // N.B. The UPS does not require the fingerprint to be a hash. However,
- // the fingerprint is limited to 32 bytes.
- iDigest->Reset();
- const TDesC& d = iRequest->Destination();
- TPtrC8 p(reinterpret_cast<const TUint8*>(d.Ptr()), d.Length() * 2);
- TPtrC8 h(iDigest->Hash(p));
-
- CFingerprint* f = CFingerprint::NewLC(h, d);
- iFingerprints->AppendL(f);
- CleanupStack::Pop(f);
-
- // An empty fingerprint may be used for decisions that apply to
- // all destinations.
- f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
- iFingerprints->AppendL(f);
- CleanupStack::Pop(f);
-
- User::RequestComplete(iClientStatus, KErrNone);
- }
-</codeblock> <p><b>Forcing prompts</b> </p> <p>You can implement the <codeph>ForcePromptL()</codeph> function
-to force a prompt, even if the UPS has found a persistent decision for the
-request in the decision database. It may be desirable to force a prompt in
-some cases such as: </p> <ul>
-<li id="GUID-4C9DDFB3-C358-534F-8E65-42E1BC672D64"><p>if a threshold has been
-reached, for example the number of MMS messages sent on a particular day </p> </li>
-<li id="GUID-5D5E02E5-DA19-5A30-8071-CD64631FBEAD"><p>if a phone user has
-selected "Never", because denying a request to a non-UPS-aware application
-may cause it to fail — the user may not realise that the previous selection
-of "Never" has caused the failure or may not know how to find the management
-application to revert the decision </p> </li>
-</ul> <p>The UPS invokes the <codeph>ForcePromptL()</codeph> function after
-a matching record is found in the database. The <codeph>ForcePromptL()</codeph> function
-is defined in the <codeph>CPolicyEvaluator</codeph> base class. The implementation
-in the base class always returns <codeph>EFalse</codeph>. To force a prompt,
-device creators need to override this function and return <codeph>ETrue</codeph>.
-A sample implementation is as follows. The <codeph>aNewEvaluatorInfo</codeph> field
-is a policy evaluator defined 32-bit field. It could be used to store usage
-thresholds or as a flag that indicates that the prompt has already been forced. </p> <codeblock id="GUID-4E60DCA5-7F25-5FC7-B173-05E1A15FCEE6" xml:space="preserve">TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord& aDecision, TUint& aNewEvaluatorInfo)
- {
- // In this example, if the user selects Never, then they are prompted
- // once more in-case they did not intend to select Never.
- // The "Evaluator Info" field is used to ensure the prompt is only forced once.
- //
- // The base class implementation (CPolicyEvaluator::ForcePromptL)
- // always returns EFalse.
- aNewEvaluatorInfo = 1;
- return (aDecision.iResult == 0 && aDecision.iEvaluatorInfo == 0);
- }
-</codeblock> <p><b>Defining default policy evaluator</b> </p> <p>If device
-creators do not define a policy evaluator, a default (internal) policy evaluator
-is returned. The default policy evaluator returns a single, null fingerprint.
-The default policy evaluator does not override the <codeph>ForcePromptL()</codeph> API. </p> </section>
-<section id="GUID-987ECDA9-5728-4A7A-AB38-D58A7CC097AC"><title> Upgrading policy evaluators </title> <p>A policy evaluator
-can be overwritten or eclipsed without restarting the UPS, if it is delivered
-through an appropriately signed upgrade. </p> <ul>
-<li id="GUID-086FABB6-13C0-5D98-8B2A-1D38BD620EB5"><p>The ECOM plug-in will
-be reloaded only when there are no active <codeph>RUpsSubsession::Authorise()</codeph> requests. </p> </li>
-<li id="GUID-CD95EB32-9438-5AA1-BA80-8C90DC304642"><p>The decision records
-are not deleted if the policy evaluator is changed. If the policy evaluator
-is not backwards compatible then new policy files with a new <codeph>majorversion</codeph> number
-should be delivered. </p> </li>
-<li id="GUID-DC1804B8-A052-52AC-96DC-32C3BBADE2A8"><p>SWI Observer informs
-the UPS that the plug-ins may have changed whenever Software Install modifies <filepath>sys\bin</filepath> on
-the system drive. There is no need to explicitly register changes to plug-ins. </p> </li>
-</ul> </section>
-<section id="GUID-48624948-C1C9-4DEA-A6E1-6E4B9AC72E8E"><title> Policy evaluator example</title> <p>The following code shows
-an example of a full implementation of the policy evaluator file: </p> <codeblock id="GUID-D1615A8D-334C-5718-BFD6-EC3004A09F3A" xml:space="preserve">#include "refpolicyevaluator.h"
-#include <ecom/implementationproxy.h>
-#include <ups/cliententity.h>
-#include <ups/fingerprint.h>
-#include <ups/upsdb.h>
-
-using namespace UserPromptService;
-
-static const TUint KRefPolicyEvaluatorImplementationId = 0x10285814;
-
-CPolicyEvaluator* CRefPolicyEvaluator::CreatePolicyEvaluatorL()
-/**
-Factory method that instantiates a new policy evaluator ECOM plug-in.
-
-@return A pointer to the new reference policy evaluator object.
-*/
- {
- CRefPolicyEvaluator* self = new (ELeave)CRefPolicyEvaluator();
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
- return self;
- }
-
-static const TImplementationProxy ImplementationTable[] =
- {
- IMPLEMENTATION_PROXY_ENTRY(KRefPolicyEvaluatorImplementationId, CRefPolicyEvaluator::CreatePolicyEvaluatorL)
- };
-
-EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
-/**
-Standard ECOM factory
-*/
- {
- aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
- return ImplementationTable;
- }
-
-
-CRefPolicyEvaluator::CRefPolicyEvaluator()
-/**
-Constructor
-*/
- : CPolicyEvaluator()
- {
- CActiveScheduler::Add(this);
- }
-
-CRefPolicyEvaluator::~CRefPolicyEvaluator()
-/**
-Destructor
-*/
- {
- Deque();
- delete iDigest;
- }
-
-void CRefPolicyEvaluator::ConstructL()
-/**
-Second phase constructor, creates the message digest
-*/
- {
- iDigest = CMessageDigestFactory::NewDigestL(CMessageDigest::EMD5);
- }
-
-// From CActive
-void CRefPolicyEvaluator::DoCancel()
- {
- // Logically should Cancel the internal outstanding requst, but
- // currently GenerateFingerprints has already completed it.
-
- // And need to complete the clients request
- if (iClientStatus)
- {
- User::RequestComplete(iClientStatus, KErrCancel);
- }
- }
-
-TInt CRefPolicyEvaluator::RunError(TInt aError)
- {
- if (iClientStatus)
- {
- User::RequestComplete(iClientStatus, aError);
- }
- return KErrNone;
- }
-
-void CRefPolicyEvaluator::RunL()
- {
- // Create most specific hash first i.e. HASH(destination)
- // Information from the opaque data supplied by the system server
- // may also be used.
- // N.B. The UPS does not require the fingerprint to be a hash. However,
- // the fingerprint is limited to 32 bytes.
- iDigest->Reset();
- const TDesC& d = iRequest->Destination();
- TPtrC8 p(reinterpret_cast<const TUint8*>(d.Ptr()), d.Length() * 2);
- TPtrC8 h(iDigest->Hash(p));
-
- CFingerprint* f = CFingerprint::NewLC(h, d);
- iFingerprints->AppendL(f);
- CleanupStack::Pop(f);
-
- // An empty fingerprint may be used for decisions that apply to
- // all destinations.
- f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
- iFingerprints->AppendL(f);
- CleanupStack::Pop(f);
-
- User::RequestComplete(iClientStatus, KErrNone);
- }
-
-void CRefPolicyEvaluator::GenerateFingerprints(
- const CPromptRequest& aRequest, const CPolicy& aPolicy,
- RPointerArray<CFingerprint>& aFingerprints, const CClientEntity*& aClientEntity,
- const TAny*& aDialogCreatorParams, TRequestStatus& aStatus)
- {
- iRequest = &aRequest;
- iPolicy = &aPolicy;
- iFingerprints = &aFingerprints;
-
- // This OUT parameter *could* be set to point to data structure
- // owned by this policy evaluator that is read by the dialog-creator.
- aDialogCreatorParams = 0;
-
- // The client entity field only needs to be set if the policy evaluator
- // is designed to identify scripts/non-native applications being executed
- // by the client application.
- aClientEntity = 0;
-
- iClientStatus = &aStatus;
- aStatus = KRequestPending;
-
- // Kick off policy evaluator state machine
- iStatus = KRequestPending;
- TRequestStatus* status = &iStatus;
- SetActive();
- User::RequestComplete(status, KErrNone);
- }
-
-TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord& aDecision, TUint& aNewEvaluatorInfo)
- {
- // In this example, if the user selects Never, then they are prompted
- // once more in-case they did not intend to select Never.
- // The "Evaluator Info" field is used to ensure the prompt is only forced once.
- //
- // The base class implementation (CPolicyEvaluator::ForcePromptL)
- // always returns EFalse.
- aNewEvaluatorInfo = 1;
- return (aDecision.iResult == 0 && aDecision.iEvaluatorInfo == 0);
- }
-</codeblock> </section>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License
+"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:
+-->
+<!DOCTYPE concept
+ PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-43080A86-72D3-5422-953E-A5EF79961D7B" xml:lang="en"><title>Writing
+a UPS Policy Evaluator</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<section id="GUID-56EDF170-1A32-4275-8799-99D13C485E1E"><title>Introduction</title> <p>Policy Evaluators are ECOM plug-ins.
+They allow security decisions to be specific to the data on which the service
+acts instead of simply granting full access to the service, for example "Allow
+application X to send SMS messages to 01234567". This is supported through
+the fingerprint functionality. They allow a security decision to be specific
+to an individual script executing within a scripting host. This is supported
+through the client entity field. And they allow a prompt to be displayed even
+if the user selected "Always" or "Never". This could be based on a usage threshold
+or simply as additional confirmation if the user selected "Never". This is
+supported through the force prompt functionality. </p> <p> <b>Note</b>: when
+a user selects “Never” or “Always”, the UPS creates a record in a decision
+database. This record identifies the system server UID, service UID, client
+SID, client entity name (name of an entity running within a client process,
+for example, a script identifier) and a "fingerprint" for a given decision. </p> <p>The
+purpose of a Policy Evaluator is to allow device creators to optionally customise
+the behaviour of the UPS at run-time. Policy Evaluators may: </p> <ul>
+<li id="GUID-1D5DD614-02E3-56AA-A0A6-A694E2311A0E"><p>Allow security decisions
+to be specific to the data on which the service acts instead of simply granting
+full access to the service, for example "Allow application X to send SMS messages
+to 01234567". This is supported via the fingerprint functionality. </p> </li>
+<li id="GUID-5B5E3EB4-5C93-5E4E-BB6E-39F889AD3610"><p>Allow a security decision
+to be specific to an individual script executing within a scripting host.
+This is supported via the client entity field. </p> </li>
+<li id="GUID-8B26DA57-A9DF-5D99-A259-2E6DF7C4DCCE"><p>Allow a prompt to be
+displayed even if the user selected "Always" or "Never". This could be based
+on a usage threshold or simply as additional confirmation if the user selected
+"Never". This is supported via the force prompt functionality. </p> </li>
+</ul> </section>
+<section id="GUID-CCBB139D-0F1C-4AD4-B2F2-062CF660A0DE"><title>Procedure</title> <p>Writing policy evaluator includes the
+following: </p> <ol id="GUID-F50174F6-3619-545A-8844-D4DA64B1B339">
+<li id="GUID-246EF2AB-23D9-5B1B-BC4C-8CCFB545C307"><p>Generating fingerprints </p> </li>
+<li id="GUID-4427FF70-9461-566A-8567-FC6EEF879475"><p>Forcing prompts </p> </li>
+<li id="GUID-703D9B83-78A0-5EA6-8D1C-685D2BC847EA"><p>Defining default policy
+evaluator </p> </li>
+</ol> <p>Policy evaluators implement the <codeph>CPolicyEvaluator</codeph> interface. </p> <p><b>Generating
+fingerprints</b> </p> <p>The key task of the policy evaluator is to generate
+fingerprints. A fingerprint is a collection of data describing the service
+being requested. The fingerprint usually includes the <codeph>destination</codeph> string,
+for example a telephone number, supplied by the service that is matched to
+the <codeph>destination</codeph> string of a policy in the policy file. </p> <p>The
+policy evaluator must implement the <codeph>GenerateFingerprints()</codeph> function,
+which is a pure virtual function, declared in the <xref href="GUID-FDE91CAC-1588-3EED-B509-08168F4B881B.dita"><apiname>CPolicyEvaluator</apiname></xref> base
+class. The function is asynchronous to allow the implementation to call other
+server processes. </p> <p>The following table describes the parameters for
+the <codeph>GenerateFingerprints()</codeph> function: </p> <table id="GUID-963D89B8-EB90-5668-8A08-588EF1E94C43">
+<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
+<thead>
+<row>
+<entry>Parameter</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><p> <codeph>aRequest</codeph> </p> </entry>
+<entry><p>Data that the system server provides to the UPS, including the ClientSid,
+ServerSid and ServiceId. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aPolicy</codeph> </p> </entry>
+<entry><p>Details of the policy for the service. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aFingerprints</codeph> </p> </entry>
+<entry><p>Array of fingerprints. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aClientEntity</codeph> </p> </entry>
+<entry><p>Details of client entity (will be null if the client process is
+not an execution host or the policy evaluator does not support client entities). </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aDialogCreatorParams</codeph> </p> </entry>
+<entry><p>Opaque data, which can be any other information for use in the fingerprint
+or to be displayed in the dialog. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aStatus</codeph> </p> </entry>
+<entry><p>The request status used to contain completion information for the
+function. </p> </entry>
+</row>
+</tbody>
+</tgroup>
+</table> <p>The following code fragment is a sample implementation of the <codeph>GenerateFingerprints()</codeph> function. </p> <codeblock id="GUID-B8555FDF-8BDD-5D22-AA20-AA9A4B35148A" xml:space="preserve">void CRefPolicyEvaluator::GenerateFingerprints(
+ const CPromptRequest& aRequest, const CPolicy& aPolicy,
+ RPointerArray<CFingerprint>& aFingerprints, const CClientEntity*& aClientEntity,
+ const TAny*& aDialogCreatorParams, TRequestStatus& aStatus)
+ {
+ iRequest = &aRequest;
+ iPolicy = &aPolicy;
+ iFingerprints = &aFingerprints;
+
+ // This OUT parameter *could* be set to point to data structure
+ // owned by this policy evaluator that is read by the dialog-creator.
+ aDialogCreatorParams = 0;
+
+ // The client entity field only needs to be set if the policy evaluator
+ // is designed to identify scripts/non-native applications being executed
+ // by the client application.
+ aClientEntity = 0;
+
+ iClientStatus = &aStatus;
+ aStatus = KRequestPending;
+
+ // Kick off policy evaluator state machine
+ iStatus = KRequestPending;
+ TRequestStatus* status = &iStatus;
+ SetActive();
+ User::RequestComplete(status, KErrNone);
+ }
+</codeblock> <p> <codeph>RunL()</codeph> is called when the request completes.
+The fingerprint is created and appended to the fingerprint array in <codeph>RunL()</codeph>.
+The following example shows a hash of a destination being created for a fingerprint
+as well as an empty fingerprint for decisions that apply to all destinations. </p> <codeblock id="GUID-EB57F6E0-C3B2-5CDC-B9FF-A570B73B4C74" xml:space="preserve">void CRefPolicyEvaluator::RunL()
+ {
+ // Create most specific hash first i.e. HASH(destination)
+ // Information from the opaque data supplied by the system server
+ // may also be used.
+ // N.B. The UPS does not require the fingerprint to be a hash. However,
+ // the fingerprint is limited to 32 bytes.
+ iDigest->Reset();
+ const TDesC& d = iRequest->Destination();
+ TPtrC8 p(reinterpret_cast<const TUint8*>(d.Ptr()), d.Length() * 2);
+ TPtrC8 h(iDigest->Hash(p));
+
+ CFingerprint* f = CFingerprint::NewLC(h, d);
+ iFingerprints->AppendL(f);
+ CleanupStack::Pop(f);
+
+ // An empty fingerprint may be used for decisions that apply to
+ // all destinations.
+ f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
+ iFingerprints->AppendL(f);
+ CleanupStack::Pop(f);
+
+ User::RequestComplete(iClientStatus, KErrNone);
+ }
+</codeblock> <p><b>Forcing prompts</b> </p> <p>You can implement the <codeph>ForcePromptL()</codeph> function
+to force a prompt, even if the UPS has found a persistent decision for the
+request in the decision database. It may be desirable to force a prompt in
+some cases such as: </p> <ul>
+<li id="GUID-4C9DDFB3-C358-534F-8E65-42E1BC672D64"><p>if a threshold has been
+reached, for example the number of MMS messages sent on a particular day </p> </li>
+<li id="GUID-5D5E02E5-DA19-5A30-8071-CD64631FBEAD"><p>if a phone user has
+selected "Never", because denying a request to a non-UPS-aware application
+may cause it to fail — the user may not realise that the previous selection
+of "Never" has caused the failure or may not know how to find the management
+application to revert the decision </p> </li>
+</ul> <p>The UPS invokes the <codeph>ForcePromptL()</codeph> function after
+a matching record is found in the database. The <codeph>ForcePromptL()</codeph> function
+is defined in the <codeph>CPolicyEvaluator</codeph> base class. The implementation
+in the base class always returns <codeph>EFalse</codeph>. To force a prompt,
+device creators need to override this function and return <codeph>ETrue</codeph>.
+A sample implementation is as follows. The <codeph>aNewEvaluatorInfo</codeph> field
+is a policy evaluator defined 32-bit field. It could be used to store usage
+thresholds or as a flag that indicates that the prompt has already been forced. </p> <codeblock id="GUID-4E60DCA5-7F25-5FC7-B173-05E1A15FCEE6" xml:space="preserve">TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord& aDecision, TUint& aNewEvaluatorInfo)
+ {
+ // In this example, if the user selects Never, then they are prompted
+ // once more in-case they did not intend to select Never.
+ // The "Evaluator Info" field is used to ensure the prompt is only forced once.
+ //
+ // The base class implementation (CPolicyEvaluator::ForcePromptL)
+ // always returns EFalse.
+ aNewEvaluatorInfo = 1;
+ return (aDecision.iResult == 0 && aDecision.iEvaluatorInfo == 0);
+ }
+</codeblock> <p><b>Defining default policy evaluator</b> </p> <p>If device
+creators do not define a policy evaluator, a default (internal) policy evaluator
+is returned. The default policy evaluator returns a single, null fingerprint.
+The default policy evaluator does not override the <codeph>ForcePromptL()</codeph> API. </p> </section>
+<section id="GUID-987ECDA9-5728-4A7A-AB38-D58A7CC097AC"><title> Upgrading policy evaluators </title> <p>A policy evaluator
+can be overwritten or eclipsed without restarting the UPS, if it is delivered
+through an appropriately signed upgrade. </p> <ul>
+<li id="GUID-086FABB6-13C0-5D98-8B2A-1D38BD620EB5"><p>The ECOM plug-in will
+be reloaded only when there are no active <codeph>RUpsSubsession::Authorise()</codeph> requests. </p> </li>
+<li id="GUID-CD95EB32-9438-5AA1-BA80-8C90DC304642"><p>The decision records
+are not deleted if the policy evaluator is changed. If the policy evaluator
+is not backwards compatible then new policy files with a new <codeph>majorversion</codeph> number
+should be delivered. </p> </li>
+<li id="GUID-DC1804B8-A052-52AC-96DC-32C3BBADE2A8"><p>SWI Observer informs
+the UPS that the plug-ins may have changed whenever Software Install modifies <filepath>sys\bin</filepath> on
+the system drive. There is no need to explicitly register changes to plug-ins. </p> </li>
+</ul> </section>
+<section id="GUID-48624948-C1C9-4DEA-A6E1-6E4B9AC72E8E"><title> Policy evaluator example</title> <p>The following code shows
+an example of a full implementation of the policy evaluator file: </p> <codeblock id="GUID-D1615A8D-334C-5718-BFD6-EC3004A09F3A" xml:space="preserve">#include "refpolicyevaluator.h"
+#include <ecom/implementationproxy.h>
+#include <ups/cliententity.h>
+#include <ups/fingerprint.h>
+#include <ups/upsdb.h>
+
+using namespace UserPromptService;
+
+static const TUint KRefPolicyEvaluatorImplementationId = 0x10285814;
+
+CPolicyEvaluator* CRefPolicyEvaluator::CreatePolicyEvaluatorL()
+/**
+Factory method that instantiates a new policy evaluator ECOM plug-in.
+
+@return A pointer to the new reference policy evaluator object.
+*/
+ {
+ CRefPolicyEvaluator* self = new (ELeave)CRefPolicyEvaluator();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+static const TImplementationProxy ImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY(KRefPolicyEvaluatorImplementationId, CRefPolicyEvaluator::CreatePolicyEvaluatorL)
+ };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+/**
+Standard ECOM factory
+*/
+ {
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+ return ImplementationTable;
+ }
+
+
+CRefPolicyEvaluator::CRefPolicyEvaluator()
+/**
+Constructor
+*/
+ : CPolicyEvaluator()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CRefPolicyEvaluator::~CRefPolicyEvaluator()
+/**
+Destructor
+*/
+ {
+ Deque();
+ delete iDigest;
+ }
+
+void CRefPolicyEvaluator::ConstructL()
+/**
+Second phase constructor, creates the message digest
+*/
+ {
+ iDigest = CMessageDigestFactory::NewDigestL(CMessageDigest::EMD5);
+ }
+
+// From CActive
+void CRefPolicyEvaluator::DoCancel()
+ {
+ // Logically should Cancel the internal outstanding requst, but
+ // currently GenerateFingerprints has already completed it.
+
+ // And need to complete the clients request
+ if (iClientStatus)
+ {
+ User::RequestComplete(iClientStatus, KErrCancel);
+ }
+ }
+
+TInt CRefPolicyEvaluator::RunError(TInt aError)
+ {
+ if (iClientStatus)
+ {
+ User::RequestComplete(iClientStatus, aError);
+ }
+ return KErrNone;
+ }
+
+void CRefPolicyEvaluator::RunL()
+ {
+ // Create most specific hash first i.e. HASH(destination)
+ // Information from the opaque data supplied by the system server
+ // may also be used.
+ // N.B. The UPS does not require the fingerprint to be a hash. However,
+ // the fingerprint is limited to 32 bytes.
+ iDigest->Reset();
+ const TDesC& d = iRequest->Destination();
+ TPtrC8 p(reinterpret_cast<const TUint8*>(d.Ptr()), d.Length() * 2);
+ TPtrC8 h(iDigest->Hash(p));
+
+ CFingerprint* f = CFingerprint::NewLC(h, d);
+ iFingerprints->AppendL(f);
+ CleanupStack::Pop(f);
+
+ // An empty fingerprint may be used for decisions that apply to
+ // all destinations.
+ f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
+ iFingerprints->AppendL(f);
+ CleanupStack::Pop(f);
+
+ User::RequestComplete(iClientStatus, KErrNone);
+ }
+
+void CRefPolicyEvaluator::GenerateFingerprints(
+ const CPromptRequest& aRequest, const CPolicy& aPolicy,
+ RPointerArray<CFingerprint>& aFingerprints, const CClientEntity*& aClientEntity,
+ const TAny*& aDialogCreatorParams, TRequestStatus& aStatus)
+ {
+ iRequest = &aRequest;
+ iPolicy = &aPolicy;
+ iFingerprints = &aFingerprints;
+
+ // This OUT parameter *could* be set to point to data structure
+ // owned by this policy evaluator that is read by the dialog-creator.
+ aDialogCreatorParams = 0;
+
+ // The client entity field only needs to be set if the policy evaluator
+ // is designed to identify scripts/non-native applications being executed
+ // by the client application.
+ aClientEntity = 0;
+
+ iClientStatus = &aStatus;
+ aStatus = KRequestPending;
+
+ // Kick off policy evaluator state machine
+ iStatus = KRequestPending;
+ TRequestStatus* status = &iStatus;
+ SetActive();
+ User::RequestComplete(status, KErrNone);
+ }
+
+TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord& aDecision, TUint& aNewEvaluatorInfo)
+ {
+ // In this example, if the user selects Never, then they are prompted
+ // once more in-case they did not intend to select Never.
+ // The "Evaluator Info" field is used to ensure the prompt is only forced once.
+ //
+ // The base class implementation (CPolicyEvaluator::ForcePromptL)
+ // always returns EFalse.
+ aNewEvaluatorInfo = 1;
+ return (aDecision.iResult == 0 && aDecision.iEvaluatorInfo == 0);
+ }
+</codeblock> </section>
</conbody></concept>
\ No newline at end of file