Symbian3/PDK/Source/GUID-A8130D83-E684-5B6C-BDFE-EB6EE3CD49E8.dita
changeset 14 578be2adaf3e
parent 5 f345bda72bc4
--- a/Symbian3/PDK/Source/GUID-A8130D83-E684-5B6C-BDFE-EB6EE3CD49E8.dita	Tue Jul 20 12:00:49 2010 +0100
+++ b/Symbian3/PDK/Source/GUID-A8130D83-E684-5B6C-BDFE-EB6EE3CD49E8.dita	Fri Aug 13 16:47:46 2010 +0100
@@ -1,498 +1,498 @@
-<?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-A8130D83-E684-5B6C-BDFE-EB6EE3CD49E8" xml:lang="en"><title>Writing
-a UPS Dialog Creator</title><prolog><metadata><keywords/></metadata></prolog><conbody>
-<section id="GUID-9383005F-53E7-465E-A10E-8A781EDB52E2"><title>Introduction</title> <p>Dialog
-creators are ECom plug-ins that device creators can write to generate the
-dialogs containing prompts for phone users. </p> <p>The plug-in has an API
-that consists of two asynchronous functions: </p> <ul>
-<li id="GUID-96CBCE79-4F5D-5F87-AC6B-C366346447AB"><p>The <codeph>PrepareDialog()</codeph> function.
-This function is called first by the UPS server. It enables the dialog creator
-to query other system servers such as AppArc or the SIS registry to retrieve
-additional information to display in the dialog. For example it might query
-the SIS registry using the client application’s secure id. </p> </li>
-<li id="GUID-A439E217-B95B-5B68-8893-BDBD61D694D1"><p>The <codeph>DisplayDialog()</codeph> function.
-This function is called second by the UPS server. It displays the prompt,
-most commonly through the notification framework. This function also returns
-the option selected by the user and, if applicable, the fingerprint for a
-new decision record. </p> </li>
-</ul> <p>The UPS displays only one prompt at a time so it is possible for
-there to be a delay between calling the function to prepare the dialog and
-the function to display the dialog. It is also possible for other dialogs
-to be displayed between the dialog being prepared and its being displayed. </p> <p>Both <codeph>PrepareDialog()</codeph> and <codeph>DisplayDialog()</codeph> are asynchronous and must support cancellation through <codeph>CActive::Cancel</codeph>.
-If either function is cancelled, the dialog creator instance is destroyed
-without calling further methods. </p> <p>The work split between <codeph>PrepareDialog()</codeph> and <codeph>DisplayDialog()</codeph> described
-above is a recommendation, and some of the functionality could be implemented
-directly in the notifier implementation. </p> <p>In the example given in this
-document, the functionality for dialogs is implemented separately from the
-functionality for policy evaluators. This allows multiple policy evaluators
-to share common UI code. However, it is possible to deliver policy evaluator
-and dialog creator plug-ins in the same DLL. </p> </section>
-<section id="GUID-38974132-906B-45C9-8C38-0C9D0F396D15"><title>Procedure</title> <p>Dialog
-creators implement the <codeph>CDialogCreator</codeph> interface. This section
-shows how to implement the functions that prepare and display the user prompt. </p> <ol id="GUID-0F29F8B7-F303-5D42-BB95-A32B1FE13A9A">
-<li id="GUID-9FDDAD1F-4B9A-516A-8A00-0C331F38C4CA"><p>Prepare a dialog using
-the <xref href="GUID-2308E2F4-A878-3B0A-951B-EFC4908AD9BB.dita"><apiname>PrepareDialog()</apiname></xref> function. </p> </li>
-<li id="GUID-45C16A52-A05E-545A-AB3A-967CCA35BB15"><p>Display the dialog using
-the <xref href="GUID-E6C3B0F0-43A7-3656-946B-5CFE97DCFC80.dita"><apiname>DisplayDialog()</apiname></xref> function. </p> </li>
-</ol> <p>The Dialog Creator plug-in creates a dialog prompt in cases where
-no previous decision is found in the decision database. </p> <p><b> Preparing
-the dialog</b> </p> <p>The parameters to <codeph>PrepareDialog()</codeph> are
-mostly <codeph>const</codeph> pointers and references to the data that has
-already been generated by the UPS or policy evaluator. </p> <p>The following
-table describes the parameters for the <codeph>PrepareDialog()</codeph> function: </p> <table id="GUID-6D139216-B6A8-55A1-8D9B-C15134198198">
-<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>A pointer to the fingerprints array generated by the policy evaluator.
-(If the user selects "Always" or “Never”, the dialog creator returns a pointer
-to an existing fingerprint object instead of re-generating the fingerprint.) </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>aEvalPrivateData</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><note/> The UPS does not allow any responses to be returned
-to the system server except those defined in the UPS policy file. If the dialog
-creator returns an option that was not specified in the policy, the request
-is rejected and <codeph>EUpsDecNo</codeph> is returned. </p><p>Your implementation
-can assume that the pointers remain valid until after <codeph>DisplayDialog()</codeph> has
-been called. </p><p>The <codeph>PrepareDialog()</codeph> function sets values. </p><p>The<codeph> DoPrepareDialogL()</codeph> function
-prepares the data for the prompt. The DoPrepareDialogL() function is called
-through a switch statement, which can be seen in the full code sample at the
-end of this. </p> <p><b>Displaying the dialog </b> </p> <p>The <codeph>DisplayDialog()</codeph> function
-displays the dialog created by <codeph>PrepareDialog()</codeph>. On completion,
-it sets the option selected by the user and the fingerprint value if “Always”
-or “Never” was selected. Usually, dialogs are displayed using the notifier
-framework, but device creators are free to use other mechanisms. </p> <p>On
-completion <codeph>iOptionSelected</codeph> must be set to the option selected
-by the user: Yes, No, Session, Always or Never. </p> <ul>
-<li id="GUID-C657A459-6ED4-59EF-9A8A-C9FE41AF2DD0"><p>If the user selects
-“Always” or “Never”, <codeph>iFingerprint</codeph> must be set to point to
-the fingerprint to use for the new decision record. Usually, this would just
-point to one of the fingerprints passed to <codeph>PrepareDialog()</codeph>,
-but generating a new fingerprint is also permitted. </p> </li>
-<li id="GUID-0E2690AB-B44B-5C8B-9365-E09BC3031398"><p>If the decision record
-already exists and <codeph>DisplayDialog()</codeph> modifies the value of <codeph>aEvaluatorInfo</codeph>,
-the record is updated with the new value. </p> </li>
-</ul> <p>In the example at the end of this section, the <codeph>DisplayDialog()</codeph> function
-sets values. The <codeph>DoDisplayDialogL()</codeph> function calls the notifier
-framework to display the dialogs. The <codeph>DoDisplayDialogL()</codeph> function
-is called through a <codeph>switch</codeph> statement, which can be seen in
-the full code sample at the end of this section: </p> </section>
-<section id="GUID-9C1BBD11-028A-4853-98FC-BF4B881BE2AF"><title>Example</title> <p>The
-following code shows an example of a full implementation of the dialog creator
-file: </p> <codeblock id="GUID-314673F2-BBA0-56C0-A76D-07862BB4592F" xml:space="preserve">#include "refdialogcreator.h"
-#include &lt;ecom/implementationproxy.h&gt;
-#include &lt;apaid.h&gt;
-#include &lt;apgcli.h&gt;
-#include &lt;ups/promptrequest.h&gt;
-#include &lt;swi/sisregistrypackage.h&gt;
-#include &lt;swi/sisregistrysession.h&gt;
-#include &lt;scs/nullstream.h&gt;
-#include &lt;s32mem.h&gt;
-
-static const TUint KRefDialogCreatorImplementationId = 0x10283694;
-
-static const TUint KRefNotifierImplementationId = 0x1028369B;
-
-CDialogCreator* CRefDialogCreator::CreateDialogCreatorL()
-/**
-Factory method that instantiates a new dialog creator EComplug-in.
-
-@return A pointer to the new reference dialog creator object.
-*/
-    {
-    CRefDialogCreator* self = new (ELeave)CRefDialogCreator();
-    CleanupStack::PushL(self);
-    self-&gt;ConstructL();
-    CleanupStack::Pop(self);
-    return self;
-    }
-
-static const TImplementationProxy ImplementationTable[] = 
-    {
-    IMPLEMENTATION_PROXY_ENTRY(KRefDialogCreatorImplementationId, CRefDialogCreator::CreateDialogCreatorL)
-    };
-
-EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt&amp; aTableCount)
-/**
-Standard EComfactory
-*/
-    {
-    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
-    return ImplementationTable;
-    }    
-    
-
-CRefDialogCreator::CRefDialogCreator() 
-/**
-Constructor
-*/
-    : CDialogCreator(), iPromptResult(), iPromptResultPckg(iPromptResult), iState(EIdle)
-    {
-    CActiveScheduler::Add(this);    
-    }
-    
-CRefDialogCreator::~CRefDialogCreator()
-/**
-Destructor
-*/
-    {
-    Deque();
-    delete iPromptData;
-    iPromptDataDes.Close();
-    iNotifier.Close();
-    }
-
-void CRefDialogCreator::ConstructL()
-/**
-Second phase constructor
-*/
-    {
-    User::LeaveIfError(iNotifier.Connect());
-    }
-
-void CRefDialogCreator::DoCancel()
-    {
-    if (iState == EProcessResult)
-        {
-        iNotifier.CancelNotifier(TUid::Uid(KRefNotifierImplementationId));
-        }
-    if (iClientStatus)
-        {
-        User::RequestComplete(iClientStatus, KErrCancel);
-        }
-    }
-    
-TInt CRefDialogCreator::RunError(TInt aError)
-    {
-    if (iClientStatus)
-        {
-        User::RequestComplete(iClientStatus, aError);
-        }
-    return KErrNone;
-    }
-
-void CRefDialogCreator::RunL()
-    {
-    User::LeaveIfError(iStatus.Int());
-    switch (iState)
-        {
-        case EPrepareDialog:
-            DoPrepareDialogL();
-            break;
-        case EDisplayDialog:
-            DoDisplayDialogL();
-            break;
-        case EProcessResult:
-            DoProcessResultL();
-            break;
-        default:
-            ASSERT(EFalse);            
-        }
-    }
-    
-void CRefDialogCreator::DoPrepareDialogL()
-    {
-    iPromptData = CPromptData::NewL();
-    
-    // Only one state at the moment but more should be
-    // added for long running operators e.g. querying the SIS registry
-    // or resolving the client entity.
-    ResolveClientNameL(iRequest-&gt;ClientSid());
-    
-    // Get the vendor name for the client process
-    ResolveVendorNameL(iRequest-&gt;ClientVid());
-    
-    // Server / Service localized names generated in notifier plug-in. 
-    iPromptData-&gt;iServerSid = iRequest-&gt;ServerSid();
-    iPromptData-&gt;iServiceId = iRequest-&gt;ServiceId();
-    
-    // Different dialog text is displayed depending on whether the client application
-    // is signed.
-    // N.B. Protected SID is assumed to be signed or included at ROM build.
-    if (iRequest-&gt;IsClientSidProtected()) iPromptData-&gt;iFlags |= ETrustedClient;
-    
-    // Use the options specified by the policy
-    iPromptData-&gt;iOptions = iPolicy-&gt;Options();
-    
-    // Add the descriptions of the fingerprints. This could be used
-    // to allow the user to grant access to all destinations 
-    // or a single destination.
-    TInt count = iFingerprints-&gt;Count();
-    for (TInt i = 0; i &lt; count; ++i)
-        {
-        HBufC* description = (*iFingerprints)[i]-&gt;Description().AllocLC();
-        iPromptData-&gt;iDescriptions.AppendL(description);
-        CleanupStack::Pop(description);
-        }
-    
-    User::RequestComplete(iClientStatus, KErrNone);
-    // DisplayDialog is invoked by the UPS, this just verifies 
-    // that PrepareDialog was called first.
-    iState = EDisplayDialog;
-    }
-    
-void CRefDialogCreator::DoDisplayDialogL()
-/**
-Uses the notifier framework to display the dialog.
-*/
-    {
-    // Externalize the prompt data to a descriptor
-    RNullWriteStream ns;
-    ns &lt;&lt; *iPromptData;
-    ns.CommitL();
-    iPromptDataDes.CreateL(ns.BytesWritten());
-    RDesWriteStream ws;    
-    ws.Open(iPromptDataDes);
-    ws &lt;&lt; *iPromptData;
-    ws.CommitL();    
-    iNotifier.StartNotifierAndGetResponse(iStatus, TUid::Uid(KRefNotifierImplementationId),
-        iPromptDataDes, iPromptResultPckg);
-    SetActive();
-    iState = EProcessResult;
-    }
-    
-void CRefDialogCreator::DoProcessResultL()
-/**
-Processes the result returned by the notifier.
-*/
-    {
-    if (iPromptResult.iSelected == CPolicy::EAlways ||
-        iPromptResult.iSelected == CPolicy::ENever)
-        {
-        // The Always or Never option was selected so return the fingerprint 
-        // for the new decision record.
-        // 
-        // In this implementation a copy of the original fingerprint is returned. However,
-        // it is permitted to return a different fingerprint e.g. a modifier description.        
-        if (iPromptResult.iDestination &gt;= 0 &amp;&amp; iPromptResult.iDestination &lt; iFingerprints-&gt;Count())        
-            {
-            *iFingerprint = (*iFingerprints)[iPromptResult.iDestination];
-            }
-        else
-            {
-            ASSERT(EFalse);    // should never happen, unless the notifier has errors.
-            }
-        }            
-    *iOptionSelected =    iPromptResult.iSelected;
-    iState = EIdle;
-    User::RequestComplete(iClientStatus, KErrNone);        
-    }
-
-void CRefDialogCreator::ResolveVendorNameL(const TVendorId&amp; aVid)
-/**
-Looks up the localized vendor name for the client process and writes
-this to iPromptData-&gt;iVendorName.
-
-Typically, this would be resolved from the SIS registry or a lookup table.
-
-@param aVid    The vendor id of the client process.
-*/
-    {
-    if (iPromptData-&gt;iVendorName.Length() != 0)
-        {
-        // already obtained vendor name from SIS registry
-        return;
-        }
-        
-    if (aVid.iId == 0x70000001)
-        {
-        _LIT(KSymbian, "XYZ Vendor");
-        iPromptData-&gt;iVendorName.Create(KSymbian);
-        }
-    else 
-        {
-        _LIT(KUnknown, "Unknown vendor");
-        iPromptData-&gt;iVendorName.Create(KUnknown);
-        }
-    }
-    
-void CRefDialogCreator::ResolveClientNameL(const TSecureId&amp; aSid)
-/**
-Generates a human readable name for the client process. In order of 
-preference the following data is returned
-
-- The AppArc caption name.
-- The localized package name that owns this SID.
-- A value from a lookup table.
-- The filename for the client process executable.
-
-@param aSid    The secure id of the client process.
-*/
-    {
-    TBool found = EFalse;
-    
-    // Although the client name from AppArc takes precedance the SIS
-    // registry is always invoked in order to retrieve the vendor name
-    found |= ResolveClientNameFromSisRegistryL(aSid);
-    found |= ResolveClientNameFromAppArcL(aSid);
-            
-    // A lookup that maps secure-ids to application names could
-    // be used here.
-
-    // Fall back to the filename of the client process
-    // The original thread may have exited so the process handle is used instead.
-    // because the client-side object e.g. RSocket may be shared between threads.
-
-    // If the process has exited then it's o.k. to leave.
-    if (! found)
-        {            
-        RProcess clientProcess;
-        User::LeaveIfError(clientProcess.Open(iRequest-&gt;ClientProcessId()));
-        CleanupClosePushL(clientProcess);
-        iPromptData-&gt;iClientName.Create(clientProcess.FileName());        
-        CleanupStack::PopAndDestroy(&amp;clientProcess); 
-        }
-    }
-
-TBool CRefDialogCreator::ResolveClientNameFromAppArcL(const TSecureId&amp; aSid)
-/**
-Gets the caption name for the application from AppArc (if available).
-
-@param    aSid    The secure id of the client process.
-@return            ETrue if a match was found in apparc; otherwise, EFalse is returned.
-*/
-    {
-    TBool found(EFalse);
-        
-    RApaLsSession apa;
-    CleanupClosePushL(apa);    
-    TInt err = apa.Connect();
-    if (err == KErrNone)
-        {        
-        TApaAppInfo* info = new(ELeave) TApaAppInfo();
-        CleanupStack::PushL(info);
-        
-        err = apa.GetAppInfo(*info, TUid::Uid(aSid));
-        if (err == KErrNone)
-            {
-            iPromptData-&gt;iClientName.Close();
-            iPromptData-&gt;iClientName.Create(info-&gt;iCaption);
-            found = ETrue;
-            }
-        else if (err != KErrNotFound)
-            {
-            User::Leave(err);
-            }    
-        CleanupStack::PopAndDestroy(info); 
-        }
-    else if (err != KErrNotFound)
-        {
-        // If the connection to apparc failed with KErrNotFound
-        // then the error is ignored becase we assume the dialog
-        // creator was invoked from text-shell
-        User::Leave(err);
-        }
-    CleanupStack::PopAndDestroy(&amp;apa);
-    return found;
-    }
-    
-TBool CRefDialogCreator::ResolveClientNameFromSisRegistryL(const TSecureId&amp; aSid)
-/**
-Retrieves the client and vendor information from the SIS registry.
-@param aSid        The secure-id of the client application to lookup in the registry.
-@return            ETrue, if the lookup was successful; otherwise, EFalse is returned.
-*/
-    {
-    TBool found(EFalse);
-    Swi::RSisRegistrySession r;
-    User::LeaveIfError(r.Connect());
-    CleanupClosePushL(r);
-    
-    Swi::CSisRegistryPackage* p(0);
-    TRAPD(err, p = r.SidToPackageL(TUid::Uid(aSid.iId)));
-    if (err == KErrNone)
-        {
-        iPromptData-&gt;iClientName.Create(p-&gt;Name());
-        iPromptData-&gt;iVendorName.Create(p-&gt;Vendor());
-        found = ETrue;
-        delete p;
-        }
-    CleanupStack::PopAndDestroy(&amp;r);
-    return found;
-    }
-
-// From CDialogCreator
-void CRefDialogCreator::PrepareDialog(
-    const UserPromptService::CPromptRequest&amp; aRequest, const CPolicy&amp; aPolicy,            
-    const RPointerArray&lt;CFingerprint&gt;&amp; aFingerprints, const CClientEntity* aClientEntity,
-    const TAny* aEvalPrivateData, TRequestStatus&amp; aStatus)
-    {
-    aStatus = KRequestPending;
-    iClientStatus = &amp;aStatus;
-    
-    iRequest = &amp;aRequest;
-    iPolicy = &amp;aPolicy;
-    iFingerprints = &amp;aFingerprints;
-    iEvalPrivateData = aEvalPrivateData;
-    (void) aClientEntity;
-
-    // Kick off dialog creator state machine
-    iState = EPrepareDialog;
-    iStatus = KRequestPending;
-    TRequestStatus* status = &amp;iStatus;
-    SetActive();
-    User::RequestComplete(status, KErrNone);
-    }
-    
-void CRefDialogCreator::DisplayDialog(CPolicy::TOptions&amp; aOptions, const CFingerprint*&amp; aFingerprint,
-        TUint&amp; aEvaluatorInfo, TRequestStatus&amp; aStatus)
-    {    
-    aStatus = KRequestPending;
-    iClientStatus = &amp;aStatus;
-    
-    iOptionSelected = &amp;aOptions;
-    iFingerprint = &amp;aFingerprint;
-    aFingerprint = 0;
-    iEvaluatorInfo = &amp;aEvaluatorInfo;
-    iClientStatus = &amp;aStatus;
-    
-    // Start state machine
-    ASSERT(iState == EDisplayDialog); // PrepareDialog should have been called first
-    iStatus = KRequestPending;
-    TRequestStatus* status = &amp;iStatus;
-    SetActive();
-    User::RequestComplete(status, KErrNone);
-    }
-</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-A8130D83-E684-5B6C-BDFE-EB6EE3CD49E8" xml:lang="en"><title>Writing
+a UPS Dialog Creator</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<section id="GUID-9383005F-53E7-465E-A10E-8A781EDB52E2"><title>Introduction</title> <p>Dialog
+creators are ECom plug-ins that device creators can write to generate the
+dialogs containing prompts for phone users. </p> <p>The plug-in has an API
+that consists of two asynchronous functions: </p> <ul>
+<li id="GUID-96CBCE79-4F5D-5F87-AC6B-C366346447AB"><p>The <codeph>PrepareDialog()</codeph> function.
+This function is called first by the UPS server. It enables the dialog creator
+to query other system servers such as AppArc or the SIS registry to retrieve
+additional information to display in the dialog. For example it might query
+the SIS registry using the client application’s secure id. </p> </li>
+<li id="GUID-A439E217-B95B-5B68-8893-BDBD61D694D1"><p>The <codeph>DisplayDialog()</codeph> function.
+This function is called second by the UPS server. It displays the prompt,
+most commonly through the notification framework. This function also returns
+the option selected by the user and, if applicable, the fingerprint for a
+new decision record. </p> </li>
+</ul> <p>The UPS displays only one prompt at a time so it is possible for
+there to be a delay between calling the function to prepare the dialog and
+the function to display the dialog. It is also possible for other dialogs
+to be displayed between the dialog being prepared and its being displayed. </p> <p>Both <codeph>PrepareDialog()</codeph> and <codeph>DisplayDialog()</codeph> are asynchronous and must support cancellation through <codeph>CActive::Cancel</codeph>.
+If either function is cancelled, the dialog creator instance is destroyed
+without calling further methods. </p> <p>The work split between <codeph>PrepareDialog()</codeph> and <codeph>DisplayDialog()</codeph> described
+above is a recommendation, and some of the functionality could be implemented
+directly in the notifier implementation. </p> <p>In the example given in this
+document, the functionality for dialogs is implemented separately from the
+functionality for policy evaluators. This allows multiple policy evaluators
+to share common UI code. However, it is possible to deliver policy evaluator
+and dialog creator plug-ins in the same DLL. </p> </section>
+<section id="GUID-38974132-906B-45C9-8C38-0C9D0F396D15"><title>Procedure</title> <p>Dialog
+creators implement the <codeph>CDialogCreator</codeph> interface. This section
+shows how to implement the functions that prepare and display the user prompt. </p> <ol id="GUID-0F29F8B7-F303-5D42-BB95-A32B1FE13A9A">
+<li id="GUID-9FDDAD1F-4B9A-516A-8A00-0C331F38C4CA"><p>Prepare a dialog using
+the <xref href="GUID-2308E2F4-A878-3B0A-951B-EFC4908AD9BB.dita"><apiname>PrepareDialog()</apiname></xref> function. </p> </li>
+<li id="GUID-45C16A52-A05E-545A-AB3A-967CCA35BB15"><p>Display the dialog using
+the <xref href="GUID-E6C3B0F0-43A7-3656-946B-5CFE97DCFC80.dita"><apiname>DisplayDialog()</apiname></xref> function. </p> </li>
+</ol> <p>The Dialog Creator plug-in creates a dialog prompt in cases where
+no previous decision is found in the decision database. </p> <p><b> Preparing
+the dialog</b> </p> <p>The parameters to <codeph>PrepareDialog()</codeph> are
+mostly <codeph>const</codeph> pointers and references to the data that has
+already been generated by the UPS or policy evaluator. </p> <p>The following
+table describes the parameters for the <codeph>PrepareDialog()</codeph> function: </p> <table id="GUID-6D139216-B6A8-55A1-8D9B-C15134198198">
+<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>A pointer to the fingerprints array generated by the policy evaluator.
+(If the user selects "Always" or “Never”, the dialog creator returns a pointer
+to an existing fingerprint object instead of re-generating the fingerprint.) </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>aEvalPrivateData</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><note/> The UPS does not allow any responses to be returned
+to the system server except those defined in the UPS policy file. If the dialog
+creator returns an option that was not specified in the policy, the request
+is rejected and <codeph>EUpsDecNo</codeph> is returned. </p><p>Your implementation
+can assume that the pointers remain valid until after <codeph>DisplayDialog()</codeph> has
+been called. </p><p>The <codeph>PrepareDialog()</codeph> function sets values. </p><p>The<codeph> DoPrepareDialogL()</codeph> function
+prepares the data for the prompt. The DoPrepareDialogL() function is called
+through a switch statement, which can be seen in the full code sample at the
+end of this. </p> <p><b>Displaying the dialog </b> </p> <p>The <codeph>DisplayDialog()</codeph> function
+displays the dialog created by <codeph>PrepareDialog()</codeph>. On completion,
+it sets the option selected by the user and the fingerprint value if “Always”
+or “Never” was selected. Usually, dialogs are displayed using the notifier
+framework, but device creators are free to use other mechanisms. </p> <p>On
+completion <codeph>iOptionSelected</codeph> must be set to the option selected
+by the user: Yes, No, Session, Always or Never. </p> <ul>
+<li id="GUID-C657A459-6ED4-59EF-9A8A-C9FE41AF2DD0"><p>If the user selects
+“Always” or “Never”, <codeph>iFingerprint</codeph> must be set to point to
+the fingerprint to use for the new decision record. Usually, this would just
+point to one of the fingerprints passed to <codeph>PrepareDialog()</codeph>,
+but generating a new fingerprint is also permitted. </p> </li>
+<li id="GUID-0E2690AB-B44B-5C8B-9365-E09BC3031398"><p>If the decision record
+already exists and <codeph>DisplayDialog()</codeph> modifies the value of <codeph>aEvaluatorInfo</codeph>,
+the record is updated with the new value. </p> </li>
+</ul> <p>In the example at the end of this section, the <codeph>DisplayDialog()</codeph> function
+sets values. The <codeph>DoDisplayDialogL()</codeph> function calls the notifier
+framework to display the dialogs. The <codeph>DoDisplayDialogL()</codeph> function
+is called through a <codeph>switch</codeph> statement, which can be seen in
+the full code sample at the end of this section: </p> </section>
+<section id="GUID-9C1BBD11-028A-4853-98FC-BF4B881BE2AF"><title>Example</title> <p>The
+following code shows an example of a full implementation of the dialog creator
+file: </p> <codeblock id="GUID-314673F2-BBA0-56C0-A76D-07862BB4592F" xml:space="preserve">#include "refdialogcreator.h"
+#include &lt;ecom/implementationproxy.h&gt;
+#include &lt;apaid.h&gt;
+#include &lt;apgcli.h&gt;
+#include &lt;ups/promptrequest.h&gt;
+#include &lt;swi/sisregistrypackage.h&gt;
+#include &lt;swi/sisregistrysession.h&gt;
+#include &lt;scs/nullstream.h&gt;
+#include &lt;s32mem.h&gt;
+
+static const TUint KRefDialogCreatorImplementationId = 0x10283694;
+
+static const TUint KRefNotifierImplementationId = 0x1028369B;
+
+CDialogCreator* CRefDialogCreator::CreateDialogCreatorL()
+/**
+Factory method that instantiates a new dialog creator EComplug-in.
+
+@return A pointer to the new reference dialog creator object.
+*/
+    {
+    CRefDialogCreator* self = new (ELeave)CRefDialogCreator();
+    CleanupStack::PushL(self);
+    self-&gt;ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+static const TImplementationProxy ImplementationTable[] = 
+    {
+    IMPLEMENTATION_PROXY_ENTRY(KRefDialogCreatorImplementationId, CRefDialogCreator::CreateDialogCreatorL)
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt&amp; aTableCount)
+/**
+Standard EComfactory
+*/
+    {
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+    }    
+    
+
+CRefDialogCreator::CRefDialogCreator() 
+/**
+Constructor
+*/
+    : CDialogCreator(), iPromptResult(), iPromptResultPckg(iPromptResult), iState(EIdle)
+    {
+    CActiveScheduler::Add(this);    
+    }
+    
+CRefDialogCreator::~CRefDialogCreator()
+/**
+Destructor
+*/
+    {
+    Deque();
+    delete iPromptData;
+    iPromptDataDes.Close();
+    iNotifier.Close();
+    }
+
+void CRefDialogCreator::ConstructL()
+/**
+Second phase constructor
+*/
+    {
+    User::LeaveIfError(iNotifier.Connect());
+    }
+
+void CRefDialogCreator::DoCancel()
+    {
+    if (iState == EProcessResult)
+        {
+        iNotifier.CancelNotifier(TUid::Uid(KRefNotifierImplementationId));
+        }
+    if (iClientStatus)
+        {
+        User::RequestComplete(iClientStatus, KErrCancel);
+        }
+    }
+    
+TInt CRefDialogCreator::RunError(TInt aError)
+    {
+    if (iClientStatus)
+        {
+        User::RequestComplete(iClientStatus, aError);
+        }
+    return KErrNone;
+    }
+
+void CRefDialogCreator::RunL()
+    {
+    User::LeaveIfError(iStatus.Int());
+    switch (iState)
+        {
+        case EPrepareDialog:
+            DoPrepareDialogL();
+            break;
+        case EDisplayDialog:
+            DoDisplayDialogL();
+            break;
+        case EProcessResult:
+            DoProcessResultL();
+            break;
+        default:
+            ASSERT(EFalse);            
+        }
+    }
+    
+void CRefDialogCreator::DoPrepareDialogL()
+    {
+    iPromptData = CPromptData::NewL();
+    
+    // Only one state at the moment but more should be
+    // added for long running operators e.g. querying the SIS registry
+    // or resolving the client entity.
+    ResolveClientNameL(iRequest-&gt;ClientSid());
+    
+    // Get the vendor name for the client process
+    ResolveVendorNameL(iRequest-&gt;ClientVid());
+    
+    // Server / Service localized names generated in notifier plug-in. 
+    iPromptData-&gt;iServerSid = iRequest-&gt;ServerSid();
+    iPromptData-&gt;iServiceId = iRequest-&gt;ServiceId();
+    
+    // Different dialog text is displayed depending on whether the client application
+    // is signed.
+    // N.B. Protected SID is assumed to be signed or included at ROM build.
+    if (iRequest-&gt;IsClientSidProtected()) iPromptData-&gt;iFlags |= ETrustedClient;
+    
+    // Use the options specified by the policy
+    iPromptData-&gt;iOptions = iPolicy-&gt;Options();
+    
+    // Add the descriptions of the fingerprints. This could be used
+    // to allow the user to grant access to all destinations 
+    // or a single destination.
+    TInt count = iFingerprints-&gt;Count();
+    for (TInt i = 0; i &lt; count; ++i)
+        {
+        HBufC* description = (*iFingerprints)[i]-&gt;Description().AllocLC();
+        iPromptData-&gt;iDescriptions.AppendL(description);
+        CleanupStack::Pop(description);
+        }
+    
+    User::RequestComplete(iClientStatus, KErrNone);
+    // DisplayDialog is invoked by the UPS, this just verifies 
+    // that PrepareDialog was called first.
+    iState = EDisplayDialog;
+    }
+    
+void CRefDialogCreator::DoDisplayDialogL()
+/**
+Uses the notifier framework to display the dialog.
+*/
+    {
+    // Externalize the prompt data to a descriptor
+    RNullWriteStream ns;
+    ns &lt;&lt; *iPromptData;
+    ns.CommitL();
+    iPromptDataDes.CreateL(ns.BytesWritten());
+    RDesWriteStream ws;    
+    ws.Open(iPromptDataDes);
+    ws &lt;&lt; *iPromptData;
+    ws.CommitL();    
+    iNotifier.StartNotifierAndGetResponse(iStatus, TUid::Uid(KRefNotifierImplementationId),
+        iPromptDataDes, iPromptResultPckg);
+    SetActive();
+    iState = EProcessResult;
+    }
+    
+void CRefDialogCreator::DoProcessResultL()
+/**
+Processes the result returned by the notifier.
+*/
+    {
+    if (iPromptResult.iSelected == CPolicy::EAlways ||
+        iPromptResult.iSelected == CPolicy::ENever)
+        {
+        // The Always or Never option was selected so return the fingerprint 
+        // for the new decision record.
+        // 
+        // In this implementation a copy of the original fingerprint is returned. However,
+        // it is permitted to return a different fingerprint e.g. a modifier description.        
+        if (iPromptResult.iDestination &gt;= 0 &amp;&amp; iPromptResult.iDestination &lt; iFingerprints-&gt;Count())        
+            {
+            *iFingerprint = (*iFingerprints)[iPromptResult.iDestination];
+            }
+        else
+            {
+            ASSERT(EFalse);    // should never happen, unless the notifier has errors.
+            }
+        }            
+    *iOptionSelected =    iPromptResult.iSelected;
+    iState = EIdle;
+    User::RequestComplete(iClientStatus, KErrNone);        
+    }
+
+void CRefDialogCreator::ResolveVendorNameL(const TVendorId&amp; aVid)
+/**
+Looks up the localized vendor name for the client process and writes
+this to iPromptData-&gt;iVendorName.
+
+Typically, this would be resolved from the SIS registry or a lookup table.
+
+@param aVid    The vendor id of the client process.
+*/
+    {
+    if (iPromptData-&gt;iVendorName.Length() != 0)
+        {
+        // already obtained vendor name from SIS registry
+        return;
+        }
+        
+    if (aVid.iId == 0x70000001)
+        {
+        _LIT(KSymbian, "XYZ Vendor");
+        iPromptData-&gt;iVendorName.Create(KSymbian);
+        }
+    else 
+        {
+        _LIT(KUnknown, "Unknown vendor");
+        iPromptData-&gt;iVendorName.Create(KUnknown);
+        }
+    }
+    
+void CRefDialogCreator::ResolveClientNameL(const TSecureId&amp; aSid)
+/**
+Generates a human readable name for the client process. In order of 
+preference the following data is returned
+
+- The AppArc caption name.
+- The localized package name that owns this SID.
+- A value from a lookup table.
+- The filename for the client process executable.
+
+@param aSid    The secure id of the client process.
+*/
+    {
+    TBool found = EFalse;
+    
+    // Although the client name from AppArc takes precedance the SIS
+    // registry is always invoked in order to retrieve the vendor name
+    found |= ResolveClientNameFromSisRegistryL(aSid);
+    found |= ResolveClientNameFromAppArcL(aSid);
+            
+    // A lookup that maps secure-ids to application names could
+    // be used here.
+
+    // Fall back to the filename of the client process
+    // The original thread may have exited so the process handle is used instead.
+    // because the client-side object e.g. RSocket may be shared between threads.
+
+    // If the process has exited then it's o.k. to leave.
+    if (! found)
+        {            
+        RProcess clientProcess;
+        User::LeaveIfError(clientProcess.Open(iRequest-&gt;ClientProcessId()));
+        CleanupClosePushL(clientProcess);
+        iPromptData-&gt;iClientName.Create(clientProcess.FileName());        
+        CleanupStack::PopAndDestroy(&amp;clientProcess); 
+        }
+    }
+
+TBool CRefDialogCreator::ResolveClientNameFromAppArcL(const TSecureId&amp; aSid)
+/**
+Gets the caption name for the application from AppArc (if available).
+
+@param    aSid    The secure id of the client process.
+@return            ETrue if a match was found in apparc; otherwise, EFalse is returned.
+*/
+    {
+    TBool found(EFalse);
+        
+    RApaLsSession apa;
+    CleanupClosePushL(apa);    
+    TInt err = apa.Connect();
+    if (err == KErrNone)
+        {        
+        TApaAppInfo* info = new(ELeave) TApaAppInfo();
+        CleanupStack::PushL(info);
+        
+        err = apa.GetAppInfo(*info, TUid::Uid(aSid));
+        if (err == KErrNone)
+            {
+            iPromptData-&gt;iClientName.Close();
+            iPromptData-&gt;iClientName.Create(info-&gt;iCaption);
+            found = ETrue;
+            }
+        else if (err != KErrNotFound)
+            {
+            User::Leave(err);
+            }    
+        CleanupStack::PopAndDestroy(info); 
+        }
+    else if (err != KErrNotFound)
+        {
+        // If the connection to apparc failed with KErrNotFound
+        // then the error is ignored becase we assume the dialog
+        // creator was invoked from text-shell
+        User::Leave(err);
+        }
+    CleanupStack::PopAndDestroy(&amp;apa);
+    return found;
+    }
+    
+TBool CRefDialogCreator::ResolveClientNameFromSisRegistryL(const TSecureId&amp; aSid)
+/**
+Retrieves the client and vendor information from the SIS registry.
+@param aSid        The secure-id of the client application to lookup in the registry.
+@return            ETrue, if the lookup was successful; otherwise, EFalse is returned.
+*/
+    {
+    TBool found(EFalse);
+    Swi::RSisRegistrySession r;
+    User::LeaveIfError(r.Connect());
+    CleanupClosePushL(r);
+    
+    Swi::CSisRegistryPackage* p(0);
+    TRAPD(err, p = r.SidToPackageL(TUid::Uid(aSid.iId)));
+    if (err == KErrNone)
+        {
+        iPromptData-&gt;iClientName.Create(p-&gt;Name());
+        iPromptData-&gt;iVendorName.Create(p-&gt;Vendor());
+        found = ETrue;
+        delete p;
+        }
+    CleanupStack::PopAndDestroy(&amp;r);
+    return found;
+    }
+
+// From CDialogCreator
+void CRefDialogCreator::PrepareDialog(
+    const UserPromptService::CPromptRequest&amp; aRequest, const CPolicy&amp; aPolicy,            
+    const RPointerArray&lt;CFingerprint&gt;&amp; aFingerprints, const CClientEntity* aClientEntity,
+    const TAny* aEvalPrivateData, TRequestStatus&amp; aStatus)
+    {
+    aStatus = KRequestPending;
+    iClientStatus = &amp;aStatus;
+    
+    iRequest = &amp;aRequest;
+    iPolicy = &amp;aPolicy;
+    iFingerprints = &amp;aFingerprints;
+    iEvalPrivateData = aEvalPrivateData;
+    (void) aClientEntity;
+
+    // Kick off dialog creator state machine
+    iState = EPrepareDialog;
+    iStatus = KRequestPending;
+    TRequestStatus* status = &amp;iStatus;
+    SetActive();
+    User::RequestComplete(status, KErrNone);
+    }
+    
+void CRefDialogCreator::DisplayDialog(CPolicy::TOptions&amp; aOptions, const CFingerprint*&amp; aFingerprint,
+        TUint&amp; aEvaluatorInfo, TRequestStatus&amp; aStatus)
+    {    
+    aStatus = KRequestPending;
+    iClientStatus = &amp;aStatus;
+    
+    iOptionSelected = &amp;aOptions;
+    iFingerprint = &amp;aFingerprint;
+    aFingerprint = 0;
+    iEvaluatorInfo = &amp;aEvaluatorInfo;
+    iClientStatus = &amp;aStatus;
+    
+    // Start state machine
+    ASSERT(iState == EDisplayDialog); // PrepareDialog should have been called first
+    iStatus = KRequestPending;
+    TRequestStatus* status = &amp;iStatus;
+    SetActive();
+    User::RequestComplete(status, KErrNone);
+    }
+</codeblock> </section>
 </conbody></concept>
\ No newline at end of file