diff -r 48780e181b38 -r 578be2adaf3e Symbian3/PDK/Source/GUID-A8130D83-E684-5B6C-BDFE-EB6EE3CD49E8.dita --- 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 @@ - - - - - -Writing -a UPS Dialog Creator -
Introduction

Dialog -creators are ECom plug-ins that device creators can write to generate the -dialogs containing prompts for phone users.

The plug-in has an API -that consists of two asynchronous functions:

    -
  • The PrepareDialog() 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.

  • -
  • The DisplayDialog() 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.

  • -

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.

Both PrepareDialog() and DisplayDialog() are asynchronous and must support cancellation through CActive::Cancel. -If either function is cancelled, the dialog creator instance is destroyed -without calling further methods.

The work split between PrepareDialog() and DisplayDialog() described -above is a recommendation, and some of the functionality could be implemented -directly in the notifier implementation.

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.

-
Procedure

Dialog -creators implement the CDialogCreator interface. This section -shows how to implement the functions that prepare and display the user prompt.

    -
  1. Prepare a dialog using -the PrepareDialog() function.

  2. -
  3. Display the dialog using -the DisplayDialog() function.

  4. -

The Dialog Creator plug-in creates a dialog prompt in cases where -no previous decision is found in the decision database.

Preparing -the dialog

The parameters to PrepareDialog() are -mostly const pointers and references to the data that has -already been generated by the UPS or policy evaluator.

The following -table describes the parameters for the PrepareDialog() function:

- - - -Parameter -Description - - - - -

aRequest

-

Data that the system server provides to the UPS, including the ClientSid, -ServerSid and ServiceId.

-
- -

aPolicy

-

Details of the policy for the service.

-
- -

aFingerprints

-

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.)

-
- -

aClientEntity

-

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).

-
- -

aEvalPrivateData

-

Opaque data, which can be any other information for use in the fingerprint -or to be displayed in the dialog.

-
- -

aStatus

-

The request status used to contain completion information for the -function.

-
- - -

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 EUpsDecNo is returned.

Your implementation -can assume that the pointers remain valid until after DisplayDialog() has -been called.

The PrepareDialog() function sets values.

The DoPrepareDialogL() 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.

Displaying the dialog

The DisplayDialog() function -displays the dialog created by PrepareDialog(). 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.

On -completion iOptionSelected must be set to the option selected -by the user: Yes, No, Session, Always or Never.

    -
  • If the user selects -“Always” or “Never”, iFingerprint 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 PrepareDialog(), -but generating a new fingerprint is also permitted.

  • -
  • If the decision record -already exists and DisplayDialog() modifies the value of aEvaluatorInfo, -the record is updated with the new value.

  • -

In the example at the end of this section, the DisplayDialog() function -sets values. The DoDisplayDialogL() function calls the notifier -framework to display the dialogs. The DoDisplayDialogL() function -is called through a switch statement, which can be seen in -the full code sample at the end of this section:

-
Example

The -following code shows an example of a full implementation of the dialog creator -file:

#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); - } -
+ + + + + +Writing +a UPS Dialog Creator +
Introduction

Dialog +creators are ECom plug-ins that device creators can write to generate the +dialogs containing prompts for phone users.

The plug-in has an API +that consists of two asynchronous functions:

    +
  • The PrepareDialog() 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.

  • +
  • The DisplayDialog() 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.

  • +

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.

Both PrepareDialog() and DisplayDialog() are asynchronous and must support cancellation through CActive::Cancel. +If either function is cancelled, the dialog creator instance is destroyed +without calling further methods.

The work split between PrepareDialog() and DisplayDialog() described +above is a recommendation, and some of the functionality could be implemented +directly in the notifier implementation.

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.

+
Procedure

Dialog +creators implement the CDialogCreator interface. This section +shows how to implement the functions that prepare and display the user prompt.

    +
  1. Prepare a dialog using +the PrepareDialog() function.

  2. +
  3. Display the dialog using +the DisplayDialog() function.

  4. +

The Dialog Creator plug-in creates a dialog prompt in cases where +no previous decision is found in the decision database.

Preparing +the dialog

The parameters to PrepareDialog() are +mostly const pointers and references to the data that has +already been generated by the UPS or policy evaluator.

The following +table describes the parameters for the PrepareDialog() function:

+ + + +Parameter +Description + + + + +

aRequest

+

Data that the system server provides to the UPS, including the ClientSid, +ServerSid and ServiceId.

+
+ +

aPolicy

+

Details of the policy for the service.

+
+ +

aFingerprints

+

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.)

+
+ +

aClientEntity

+

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).

+
+ +

aEvalPrivateData

+

Opaque data, which can be any other information for use in the fingerprint +or to be displayed in the dialog.

+
+ +

aStatus

+

The request status used to contain completion information for the +function.

+
+ + +

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 EUpsDecNo is returned.

Your implementation +can assume that the pointers remain valid until after DisplayDialog() has +been called.

The PrepareDialog() function sets values.

The DoPrepareDialogL() 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.

Displaying the dialog

The DisplayDialog() function +displays the dialog created by PrepareDialog(). 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.

On +completion iOptionSelected must be set to the option selected +by the user: Yes, No, Session, Always or Never.

    +
  • If the user selects +“Always” or “Never”, iFingerprint 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 PrepareDialog(), +but generating a new fingerprint is also permitted.

  • +
  • If the decision record +already exists and DisplayDialog() modifies the value of aEvaluatorInfo, +the record is updated with the new value.

  • +

In the example at the end of this section, the DisplayDialog() function +sets values. The DoDisplayDialogL() function calls the notifier +framework to display the dialogs. The DoDisplayDialogL() function +is called through a switch statement, which can be seen in +the full code sample at the end of this section:

+
Example

The +following code shows an example of a full implementation of the dialog creator +file:

#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); + } +
\ No newline at end of file