diff -r d15a50675083 -r c0a997472b1c networkcontrol/ipupsplugins/dialogcreator/source/ipupsdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkcontrol/ipupsplugins/dialogcreator/source/ipupsdialog.cpp Fri Jun 11 15:15:43 2010 +0300 @@ -0,0 +1,440 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// +// Description: +// +#include // Included here, since removal of Platform headers from public headers[f32file.h] for TB92SDK +#include "ipupsdialog.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipupsconst.h" + +static const TUint KIpDialogCreatorImplementationId = 0x10285A7C; + +CIpUpsDialog* CIpUpsDialog::CreateDialogCreatorL() +/** +Factory method that instantiates a new dialog creator ECOM plug-in. + +@return A pointer to the new reference dialog creator object. +*/ + { + CIpUpsDialog* self = new (ELeave)CIpUpsDialog(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KIpDialogCreatorImplementationId, CIpUpsDialog::CreateDialogCreatorL) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) +/** +Standard ECOM factory +*/ + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return ImplementationTable; + } + + +CIpUpsDialog::CIpUpsDialog() +/** +Constructor +*/ + : CDialogCreator(), iPromptResult(),iPromptResultPckg(iPromptResult), iState(EIdle) + { + CActiveScheduler::Add(this); + } + +CIpUpsDialog::~CIpUpsDialog() +/** +Destructor +*/ + { + Deque(); + iPromptDataDes.Close(); + delete iPromptData; + iNotifier.Close(); + } + +void CIpUpsDialog::ConstructL() +/** +Second phase constructor +*/ + { + User::LeaveIfError(iNotifier.Connect()); + + // setup the value for the notifier. Test or reference +#if (defined (__EABI__) || defined (__GCCXML__)) + // this value is patched via the patchable constant mechanism + iNotifierId = KNotifierImplementationId; +#else + TUint notifierUidVal = 0; + TInt retCode = UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, + (TAny*)"NETWORKING_UPS_NOTIFIERUID", ¬ifierUidVal); + + if (retCode == KErrNone) + { + iNotifierId = notifierUidVal; + } + else + { + TUint startupModeVal = 0; + retCode = UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, + (TAny*)"startupmode", &startupModeVal); + + if(retCode == KErrNone && startupModeVal == 1) + iNotifierId = KTestNotifierImplementationId; + else + iNotifierId = KNotifierImplementationId; + } +#endif + } + +void CIpUpsDialog::DoCancel() + { + if (iState == EProcessResult) + { + iNotifier.CancelNotifier(TUid::Uid(iNotifierId)); + } + + if (iClientStatus) + { + User::RequestComplete(iClientStatus, KErrCancel); + } + } + +TInt CIpUpsDialog::RunError(TInt aError) + { + if (iClientStatus) + { + User::RequestComplete(iClientStatus, aError); + } + return KErrNone; + } + +void CIpUpsDialog::RunL() + { + User::LeaveIfError(iStatus.Int()); + switch (iState) + { + case EPrepareDialog: + DoPrepareDialogL(); + break; + case EDisplayDialog: + DoDisplayDialogL(); + break; + case EProcessResult: + DoProcessResultL(); + break; + default: + ASSERT(EFalse); + } + } + +void CIpUpsDialog::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()); + + // pass the destination information through. + iPromptData->iDestination.Create(iRequest->Destination()); + + // Pass any opaque data from the user to the notifier + iPromptData->iOpaqueData.Create(iRequest->OpaqueData()); + + // 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 CIpUpsDialog::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(iNotifierId), + iPromptDataDes, iPromptResultPckg); + SetActive(); + iState = EProcessResult; + } + +void CIpUpsDialog::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 notifier is buggy. + } + } + + // ensure the notifier has returned a valid option specified in policy file + if(iPromptResult.iSelected & iPromptData->iOptions) + { + *iOptionSelected = iPromptResult.iSelected; + } + else + { + ASSERT(EFalse); + } + + iState = EIdle; + User::RequestComplete(iClientStatus, KErrNone); + } + +void CIpUpsDialog::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, "Symbian Software Ltd"); + iPromptData->iVendorName.Create(KSymbian); + } + else + { + _LIT(KUnknown, "Unknown vendor"); + iPromptData->iVendorName.Create(KUnknown); + } + } + +void CIpUpsDialog::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 CIpUpsDialog::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 CIpUpsDialog::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(aSid)); + 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 CIpUpsDialog::PrepareDialog(const UserPromptService::CPromptRequest& aRequest, + const CPolicy& aPolicy, + const RPointerArray& 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 CIpUpsDialog::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); + } +