--- 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 <ecom/implementationproxy.h>
-#include <apaid.h>
-#include <apgcli.h>
-#include <ups/promptrequest.h>
-#include <swi/sisregistrypackage.h>
-#include <swi/sisregistrysession.h>
-#include <scs/nullstream.h>
-#include <s32mem.h>
-
-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->ConstructL();
- CleanupStack::Pop(self);
- return self;
- }
-
-static const TImplementationProxy ImplementationTable[] =
- {
- IMPLEMENTATION_PROXY_ENTRY(KRefDialogCreatorImplementationId, CRefDialogCreator::CreateDialogCreatorL)
- };
-
-EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& 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->ClientSid());
-
- // Get the vendor name for the client process
- ResolveVendorNameL(iRequest->ClientVid());
-
- // Server / Service localized names generated in notifier plug-in.
- iPromptData->iServerSid = iRequest->ServerSid();
- iPromptData->iServiceId = iRequest->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->IsClientSidProtected()) iPromptData->iFlags |= ETrustedClient;
-
- // Use the options specified by the policy
- iPromptData->iOptions = iPolicy->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->Count();
- for (TInt i = 0; i < count; ++i)
- {
- HBufC* description = (*iFingerprints)[i]->Description().AllocLC();
- iPromptData->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 << *iPromptData;
- ns.CommitL();
- iPromptDataDes.CreateL(ns.BytesWritten());
- RDesWriteStream ws;
- ws.Open(iPromptDataDes);
- ws << *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 >= 0 && iPromptResult.iDestination < iFingerprints->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& aVid)
-/**
-Looks up the localized vendor name for the client process and writes
-this to iPromptData->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->iVendorName.Length() != 0)
- {
- // already obtained vendor name from SIS registry
- return;
- }
-
- if (aVid.iId == 0x70000001)
- {
- _LIT(KSymbian, "XYZ Vendor");
- iPromptData->iVendorName.Create(KSymbian);
- }
- else
- {
- _LIT(KUnknown, "Unknown vendor");
- iPromptData->iVendorName.Create(KUnknown);
- }
- }
-
-void CRefDialogCreator::ResolveClientNameL(const TSecureId& 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->ClientProcessId()));
- CleanupClosePushL(clientProcess);
- iPromptData->iClientName.Create(clientProcess.FileName());
- CleanupStack::PopAndDestroy(&clientProcess);
- }
- }
-
-TBool CRefDialogCreator::ResolveClientNameFromAppArcL(const TSecureId& 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->iClientName.Close();
- iPromptData->iClientName.Create(info->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(&apa);
- return found;
- }
-
-TBool CRefDialogCreator::ResolveClientNameFromSisRegistryL(const TSecureId& 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->iClientName.Create(p->Name());
- iPromptData->iVendorName.Create(p->Vendor());
- found = ETrue;
- delete p;
- }
- CleanupStack::PopAndDestroy(&r);
- return found;
- }
-
-// From CDialogCreator
-void CRefDialogCreator::PrepareDialog(
- const UserPromptService::CPromptRequest& aRequest, const CPolicy& aPolicy,
- const RPointerArray<CFingerprint>& aFingerprints, const CClientEntity* aClientEntity,
- const TAny* aEvalPrivateData, TRequestStatus& aStatus)
- {
- aStatus = KRequestPending;
- iClientStatus = &aStatus;
-
- iRequest = &aRequest;
- iPolicy = &aPolicy;
- iFingerprints = &aFingerprints;
- iEvalPrivateData = aEvalPrivateData;
- (void) aClientEntity;
-
- // Kick off dialog creator state machine
- iState = EPrepareDialog;
- iStatus = KRequestPending;
- TRequestStatus* status = &iStatus;
- SetActive();
- User::RequestComplete(status, KErrNone);
- }
-
-void CRefDialogCreator::DisplayDialog(CPolicy::TOptions& aOptions, const CFingerprint*& aFingerprint,
- TUint& aEvaluatorInfo, TRequestStatus& aStatus)
- {
- aStatus = KRequestPending;
- iClientStatus = &aStatus;
-
- iOptionSelected = &aOptions;
- iFingerprint = &aFingerprint;
- aFingerprint = 0;
- iEvaluatorInfo = &aEvaluatorInfo;
- iClientStatus = &aStatus;
-
- // Start state machine
- ASSERT(iState == EDisplayDialog); // PrepareDialog should have been called first
- iStatus = KRequestPending;
- TRequestStatus* status = &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 <ecom/implementationproxy.h>
+#include <apaid.h>
+#include <apgcli.h>
+#include <ups/promptrequest.h>
+#include <swi/sisregistrypackage.h>
+#include <swi/sisregistrysession.h>
+#include <scs/nullstream.h>
+#include <s32mem.h>
+
+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->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+static const TImplementationProxy ImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY(KRefDialogCreatorImplementationId, CRefDialogCreator::CreateDialogCreatorL)
+ };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& 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->ClientSid());
+
+ // Get the vendor name for the client process
+ ResolveVendorNameL(iRequest->ClientVid());
+
+ // Server / Service localized names generated in notifier plug-in.
+ iPromptData->iServerSid = iRequest->ServerSid();
+ iPromptData->iServiceId = iRequest->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->IsClientSidProtected()) iPromptData->iFlags |= ETrustedClient;
+
+ // Use the options specified by the policy
+ iPromptData->iOptions = iPolicy->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->Count();
+ for (TInt i = 0; i < count; ++i)
+ {
+ HBufC* description = (*iFingerprints)[i]->Description().AllocLC();
+ iPromptData->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 << *iPromptData;
+ ns.CommitL();
+ iPromptDataDes.CreateL(ns.BytesWritten());
+ RDesWriteStream ws;
+ ws.Open(iPromptDataDes);
+ ws << *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 >= 0 && iPromptResult.iDestination < iFingerprints->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& aVid)
+/**
+Looks up the localized vendor name for the client process and writes
+this to iPromptData->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->iVendorName.Length() != 0)
+ {
+ // already obtained vendor name from SIS registry
+ return;
+ }
+
+ if (aVid.iId == 0x70000001)
+ {
+ _LIT(KSymbian, "XYZ Vendor");
+ iPromptData->iVendorName.Create(KSymbian);
+ }
+ else
+ {
+ _LIT(KUnknown, "Unknown vendor");
+ iPromptData->iVendorName.Create(KUnknown);
+ }
+ }
+
+void CRefDialogCreator::ResolveClientNameL(const TSecureId& 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->ClientProcessId()));
+ CleanupClosePushL(clientProcess);
+ iPromptData->iClientName.Create(clientProcess.FileName());
+ CleanupStack::PopAndDestroy(&clientProcess);
+ }
+ }
+
+TBool CRefDialogCreator::ResolveClientNameFromAppArcL(const TSecureId& 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->iClientName.Close();
+ iPromptData->iClientName.Create(info->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(&apa);
+ return found;
+ }
+
+TBool CRefDialogCreator::ResolveClientNameFromSisRegistryL(const TSecureId& 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->iClientName.Create(p->Name());
+ iPromptData->iVendorName.Create(p->Vendor());
+ found = ETrue;
+ delete p;
+ }
+ CleanupStack::PopAndDestroy(&r);
+ return found;
+ }
+
+// From CDialogCreator
+void CRefDialogCreator::PrepareDialog(
+ const UserPromptService::CPromptRequest& aRequest, const CPolicy& aPolicy,
+ const RPointerArray<CFingerprint>& aFingerprints, const CClientEntity* aClientEntity,
+ const TAny* aEvalPrivateData, TRequestStatus& aStatus)
+ {
+ aStatus = KRequestPending;
+ iClientStatus = &aStatus;
+
+ iRequest = &aRequest;
+ iPolicy = &aPolicy;
+ iFingerprints = &aFingerprints;
+ iEvalPrivateData = aEvalPrivateData;
+ (void) aClientEntity;
+
+ // Kick off dialog creator state machine
+ iState = EPrepareDialog;
+ iStatus = KRequestPending;
+ TRequestStatus* status = &iStatus;
+ SetActive();
+ User::RequestComplete(status, KErrNone);
+ }
+
+void CRefDialogCreator::DisplayDialog(CPolicy::TOptions& aOptions, const CFingerprint*& aFingerprint,
+ TUint& aEvaluatorInfo, TRequestStatus& aStatus)
+ {
+ aStatus = KRequestPending;
+ iClientStatus = &aStatus;
+
+ iOptionSelected = &aOptions;
+ iFingerprint = &aFingerprint;
+ aFingerprint = 0;
+ iEvaluatorInfo = &aEvaluatorInfo;
+ iClientStatus = &aStatus;
+
+ // Start state machine
+ ASSERT(iState == EDisplayDialog); // PrepareDialog should have been called first
+ iStatus = KRequestPending;
+ TRequestStatus* status = &iStatus;
+ SetActive();
+ User::RequestComplete(status, KErrNone);
+ }
+</codeblock> </section>
</conbody></concept>
\ No newline at end of file