networkcontrol/ipupsplugins/dialogcreator/source/ipupsdialog.cpp
branchRCL_3
changeset 5 1422c6cd3f0c
parent 1 a579325b79dd
child 6 e7dfaa7b0b8d
child 10 c64cefac6e99
equal deleted inserted replaced
1:a579325b79dd 5:1422c6cd3f0c
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 #include <e32svr.h> // Included here, since removal of Platform headers from public headers[f32file.h] for TB92SDK 
       
    16 #include "ipupsdialog.h"
       
    17 #include <ecom/implementationproxy.h>
       
    18 #include <apgcli.h>
       
    19 #include <ups/promptrequest.h>
       
    20 #include <swi/sisregistrypackage.h>
       
    21 #include <swi/sisregistrysession.h>
       
    22 #include <scs/nullstream.h>
       
    23 #include <s32mem.h>
       
    24 #include <u32hal.h>
       
    25 
       
    26 #include "ipupsconst.h"
       
    27 
       
    28 static const TUint KIpDialogCreatorImplementationId = 0x10285A7C;
       
    29 
       
    30 CIpUpsDialog* CIpUpsDialog::CreateDialogCreatorL()
       
    31 /**
       
    32 Factory method that instantiates a new dialog creator ECOM plug-in.
       
    33 
       
    34 @return A pointer to the new reference dialog creator object.
       
    35 */
       
    36    {
       
    37    CIpUpsDialog* self = new (ELeave)CIpUpsDialog();
       
    38    CleanupStack::PushL(self);
       
    39    self->ConstructL();
       
    40    CleanupStack::Pop(self);
       
    41    return self;
       
    42    }
       
    43 
       
    44 const TImplementationProxy ImplementationTable[] = 
       
    45    {
       
    46    IMPLEMENTATION_PROXY_ENTRY(KIpDialogCreatorImplementationId, CIpUpsDialog::CreateDialogCreatorL)
       
    47    };
       
    48 
       
    49 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
    50 /**
       
    51 Standard ECOM factory
       
    52 */
       
    53    {
       
    54    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
    55    return ImplementationTable;
       
    56    }	
       
    57 	
       
    58 
       
    59 CIpUpsDialog::CIpUpsDialog() 
       
    60 /**
       
    61 Constructor
       
    62 */
       
    63    : CDialogCreator(), iPromptResult(),iPromptResultPckg(iPromptResult), iState(EIdle)
       
    64    {
       
    65    CActiveScheduler::Add(this);
       
    66    }
       
    67 	
       
    68 CIpUpsDialog::~CIpUpsDialog()
       
    69 /**
       
    70 Destructor
       
    71 */
       
    72    {
       
    73    Deque();
       
    74    iPromptDataDes.Close();
       
    75    delete iPromptData;
       
    76    iNotifier.Close();
       
    77    }
       
    78 
       
    79 void CIpUpsDialog::ConstructL()
       
    80 /**
       
    81 Second phase constructor
       
    82 */
       
    83    {
       
    84    User::LeaveIfError(iNotifier.Connect());
       
    85    
       
    86    // setup the value for the notifier. Test or reference
       
    87 #if (defined (__EABI__)  ||  defined (__GCCXML__))
       
    88    // this value is patched via the patchable constant mechanism
       
    89    iNotifierId = KNotifierImplementationId;
       
    90 #else
       
    91    TUint notifierUidVal = 0;
       
    92    TInt retCode = UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty,
       
    93 		   (TAny*)"NETWORKING_UPS_NOTIFIERUID", &notifierUidVal);
       
    94 
       
    95    if (retCode == KErrNone)
       
    96 	   {
       
    97 	   iNotifierId = notifierUidVal;
       
    98 	   }
       
    99    else
       
   100 	   {
       
   101 	   TUint startupModeVal = 0;
       
   102 	   retCode = UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty,
       
   103 			   (TAny*)"startupmode", &startupModeVal);
       
   104 	   
       
   105 	   if(retCode == KErrNone && startupModeVal == 1)
       
   106 		   iNotifierId = KTestNotifierImplementationId;
       
   107 	   else
       
   108 		   iNotifierId = KNotifierImplementationId;
       
   109 	   }  
       
   110 #endif   
       
   111    }
       
   112 
       
   113 void CIpUpsDialog::DoCancel()
       
   114    {
       
   115    if (iState == EProcessResult)
       
   116       {
       
   117       iNotifier.CancelNotifier(TUid::Uid(iNotifierId));
       
   118       }
       
   119    
       
   120    if (iClientStatus)
       
   121       {
       
   122       User::RequestComplete(iClientStatus, KErrCancel);
       
   123       }
       
   124    }
       
   125 	
       
   126 TInt CIpUpsDialog::RunError(TInt aError)
       
   127    {
       
   128    if (iClientStatus)
       
   129       {
       
   130       User::RequestComplete(iClientStatus, aError);
       
   131       }
       
   132    return KErrNone;
       
   133    }
       
   134 
       
   135 void CIpUpsDialog::RunL()
       
   136    {
       
   137    User::LeaveIfError(iStatus.Int());
       
   138    switch (iState)
       
   139       {
       
   140       case EPrepareDialog:
       
   141          DoPrepareDialogL();
       
   142          break;
       
   143       case EDisplayDialog:
       
   144 	     DoDisplayDialogL();
       
   145          break;
       
   146       case EProcessResult:
       
   147          DoProcessResultL();
       
   148          break;
       
   149       default:
       
   150          ASSERT(EFalse);			
       
   151       }
       
   152    }
       
   153 	
       
   154 void CIpUpsDialog::DoPrepareDialogL()
       
   155    {
       
   156    iPromptData = CPromptData::NewL();
       
   157 	
       
   158    // Only one state at the moment but more should be
       
   159    // added for long running operators e.g. querying the SIS registry
       
   160    // or resolving the client entity.
       
   161    ResolveClientNameL(iRequest->ClientSid());
       
   162 	
       
   163    // Get the vendor name for the client process
       
   164    ResolveVendorNameL(iRequest->ClientVid());
       
   165 	
       
   166    // pass the destination information through.
       
   167    iPromptData->iDestination.Create(iRequest->Destination());
       
   168   
       
   169    // Pass any opaque data from the user to the notifier
       
   170    iPromptData->iOpaqueData.Create(iRequest->OpaqueData());
       
   171 
       
   172    // Server / Service localized names generated in notifier plug-in. 
       
   173    iPromptData->iServerSid = iRequest->ServerSid();
       
   174    iPromptData->iServiceId = iRequest->ServiceId();
       
   175 	
       
   176    // Different dialog text is displayed depending on whether the client application
       
   177    // is signed.
       
   178    // N.B. Protected SID is assumed to be signed or included at ROM build.
       
   179    if (iRequest->IsClientSidProtected()) iPromptData->iFlags |= ETrustedClient;
       
   180 	
       
   181    // Use the options specified by the policy
       
   182    iPromptData->iOptions = iPolicy->Options();
       
   183 	
       
   184    // Add the descriptions of the fingerprints. This could be used
       
   185    // to allow the user to grant access to all destinations 
       
   186    // or a single destination.
       
   187    TInt count = iFingerprints->Count();
       
   188    for (TInt i = 0; i < count; ++i)
       
   189       {
       
   190       HBufC* description = (*iFingerprints)[i]->Description().AllocLC();
       
   191       iPromptData->iDescriptions.AppendL(description);
       
   192       CleanupStack::Pop(description);
       
   193       }
       
   194 	
       
   195    User::RequestComplete(iClientStatus, KErrNone);		
       
   196    // DisplayDialog is invoked by the UPS, this just verifies 
       
   197    // that PrepareDialog was called first.
       
   198    iState = EDisplayDialog;
       
   199    }
       
   200 	
       
   201 void CIpUpsDialog::DoDisplayDialogL()
       
   202 /**
       
   203 Uses the notifier framework to display the dialog.
       
   204 */
       
   205    {
       
   206    // Externalize the prompt data to a descriptor
       
   207    RNullWriteStream ns;
       
   208    ns << *iPromptData;
       
   209    ns.CommitL();
       
   210    iPromptDataDes.CreateL(ns.BytesWritten());
       
   211    RDesWriteStream ws;	
       
   212    ws.Open(iPromptDataDes);
       
   213    ws << *iPromptData;
       
   214    ws.CommitL();	
       
   215    iNotifier.StartNotifierAndGetResponse(iStatus, TUid::Uid(iNotifierId),
       
   216                                          iPromptDataDes, iPromptResultPckg);
       
   217    SetActive();
       
   218    iState = EProcessResult;
       
   219    }
       
   220 	
       
   221 void CIpUpsDialog::DoProcessResultL()
       
   222 /**
       
   223 Processes the result returned by the notifier.
       
   224 */
       
   225    {			
       
   226    if(iPromptResult.iSelected == CPolicy::EAlways || iPromptResult.iSelected == CPolicy::ENever)
       
   227       {
       
   228       // The Always or Never option was selected so return the fingerprint 
       
   229       // for the new decision record.
       
   230       // 
       
   231       // In this implementation a copy of the original fingerprint is returned. However,
       
   232       // it is permitted to return a different fingerprint e.g. a modifier description.       
       
   233       if(iPromptResult.iDestination >= 0 && iPromptResult.iDestination < iFingerprints->Count())     
       
   234          {
       
   235          *iFingerprint = (*iFingerprints)[iPromptResult.iDestination];
       
   236          }
       
   237       else
       
   238          {
       
   239          ASSERT(EFalse); // should never happen, unless notifier is buggy.
       
   240          }
       
   241       }   
       
   242 
       
   243     // ensure the notifier has returned a valid option specified in policy file
       
   244    if(iPromptResult.iSelected & iPromptData->iOptions)
       
   245       {
       
   246       *iOptionSelected = iPromptResult.iSelected;
       
   247       }
       
   248    else
       
   249       {
       
   250       ASSERT(EFalse); 
       
   251       }
       
   252       
       
   253    iState = EIdle;
       
   254    User::RequestComplete(iClientStatus, KErrNone);	
       
   255    }
       
   256 
       
   257 void CIpUpsDialog::ResolveVendorNameL(const TVendorId& aVid)
       
   258 /**
       
   259 Looks up the localized vendor name for the client process and writes
       
   260 this to iPromptData.iVendorName.
       
   261 
       
   262 Typically, this would be resolved from the SIS registry or a lookup table.
       
   263 
       
   264 @param aVid	The vendor id of the client process.
       
   265 */
       
   266    {
       
   267    if (iPromptData->iVendorName.Length() != 0)
       
   268       {
       
   269       // already obtained vendor name from SIS registry
       
   270       return;
       
   271       }
       
   272 		
       
   273    if (aVid.iId == 0x70000001)
       
   274       {
       
   275       _LIT(KSymbian, "Symbian Software Ltd");
       
   276       iPromptData->iVendorName.Create(KSymbian);
       
   277       }
       
   278    else 
       
   279       {
       
   280       _LIT(KUnknown, "Unknown vendor");
       
   281       iPromptData->iVendorName.Create(KUnknown);
       
   282       }
       
   283    }
       
   284 	
       
   285 void CIpUpsDialog::ResolveClientNameL(const TSecureId& aSid)
       
   286 /**
       
   287 Generates a human readable name for the client process. In order of 
       
   288 preference the following data is returned
       
   289 
       
   290 - The AppArc caption name.
       
   291 - The localized package name that owns this SID.
       
   292 - A value from a lookup table.
       
   293 - The filename for the client process executable.
       
   294 
       
   295 @param aSid	The secure id of the client process.
       
   296 */
       
   297    {
       
   298    TBool found = EFalse;
       
   299 	
       
   300    // Although the client name from AppArc takes precedance the SIS
       
   301    // registry is always invoked in order to retrieve the vendor name
       
   302    found |= ResolveClientNameFromSisRegistryL(aSid);
       
   303    found |= ResolveClientNameFromAppArcL(aSid);
       
   304 			
       
   305    // A lookup that maps secure-ids to application names could
       
   306    // be used here.
       
   307 
       
   308    // Fall back to the filename of the client process
       
   309    // The original thread may have exited so the process handle is used instead.
       
   310    // because the client-side object e.g. RSocket may be shared between threads.
       
   311 
       
   312    // If the process has exited then it's o.k. to leave.
       
   313    if (! found)
       
   314       {			
       
   315       RProcess clientProcess;
       
   316       User::LeaveIfError(clientProcess.Open(iRequest->ClientProcessId()));
       
   317       CleanupClosePushL(clientProcess);
       
   318       iPromptData->iClientName.Create(clientProcess.FileName());		
       
   319       CleanupStack::PopAndDestroy(&clientProcess); 
       
   320       }
       
   321    }
       
   322 
       
   323 TBool CIpUpsDialog::ResolveClientNameFromAppArcL(const TSecureId& aSid)
       
   324 /**
       
   325 Gets the caption name for the application from AppArc (if available).
       
   326 
       
   327 @param	aSid	The secure id of the client process.
       
   328 @return		ETrue if a match was found in apparc; otherwise, EFalse is returned.
       
   329 */
       
   330    {
       
   331    TBool found(EFalse);
       
   332 	
       
   333    RApaLsSession apa;
       
   334    CleanupClosePushL(apa);	
       
   335    TInt err = apa.Connect();
       
   336    if (err == KErrNone)
       
   337       {		
       
   338       TApaAppInfo* info = new(ELeave) TApaAppInfo();
       
   339       CleanupStack::PushL(info);
       
   340 		
       
   341       err = apa.GetAppInfo(*info, TUid::Uid(aSid));
       
   342       
       
   343       if (err == KErrNone)
       
   344          {
       
   345          iPromptData->iClientName.Close();
       
   346          iPromptData->iClientName.Create(info->iCaption);
       
   347          found = ETrue;
       
   348 	     }
       
   349       else if (err != KErrNotFound)
       
   350 	     {
       
   351 	     User::Leave(err);
       
   352 	     }	
       
   353       
       
   354       CleanupStack::PopAndDestroy(info);
       
   355       }
       
   356    else if (err != KErrNotFound)
       
   357       {
       
   358       // If the connection to apparc failed with KErrNotFound
       
   359       // then the error is ignored becase we assume the dialog
       
   360       // creator was invoked from text-shell
       
   361       User::Leave(err);
       
   362       }
       
   363    
       
   364    CleanupStack::PopAndDestroy(&apa);
       
   365    return found;
       
   366    }
       
   367 
       
   368 TBool CIpUpsDialog::ResolveClientNameFromSisRegistryL(const TSecureId& aSid)
       
   369 /**
       
   370 Retrieves the client and vendor information from the SIS registry.
       
   371 @param aSid		The secure-id of the client application to lookup in the registry.
       
   372 @return			ETrue, if the lookup was successful; otherwise, EFalse is returned.
       
   373 */
       
   374    {
       
   375    TBool found(EFalse);
       
   376    Swi::RSisRegistrySession r;
       
   377    User::LeaveIfError(r.Connect());
       
   378    CleanupClosePushL(r);
       
   379 	
       
   380    Swi::CSisRegistryPackage* p(0);
       
   381    TRAPD(err, p = r.SidToPackageL(aSid));
       
   382    if (err == KErrNone)
       
   383       {
       
   384       iPromptData->iClientName.Create(p->Name());
       
   385       iPromptData->iVendorName.Create(p->Vendor());
       
   386       found = ETrue;
       
   387       delete p;
       
   388       }
       
   389    
       
   390    CleanupStack::PopAndDestroy(&r);
       
   391    return found;
       
   392    }
       
   393 
       
   394 // From CDialogCreator
       
   395 void CIpUpsDialog::PrepareDialog(const UserPromptService::CPromptRequest& aRequest, 
       
   396                                  const CPolicy& aPolicy,			
       
   397                                  const RPointerArray<CFingerprint>& aFingerprints, 
       
   398                                  const CClientEntity* aClientEntity, 
       
   399                                  const TAny* aEvalPrivateData, 
       
   400                                  TRequestStatus& aStatus)
       
   401    {
       
   402    aStatus = KRequestPending;
       
   403    iClientStatus = &aStatus;
       
   404 	
       
   405    iRequest = &aRequest;
       
   406    iPolicy = &aPolicy;
       
   407    iFingerprints = &aFingerprints;
       
   408    iEvalPrivateData = aEvalPrivateData;
       
   409    (void) aClientEntity;
       
   410 
       
   411    // Kick off dialog creator state machine
       
   412    iState = EPrepareDialog;
       
   413    iStatus = KRequestPending;
       
   414    TRequestStatus* status = &iStatus;
       
   415    SetActive();
       
   416    User::RequestComplete(status, KErrNone);
       
   417    }
       
   418 	
       
   419 void CIpUpsDialog::DisplayDialog(CPolicy::TOptions& aOptions, 
       
   420                                  const CFingerprint*& aFingerprint,
       
   421                                  TUint& aEvaluatorInfo,
       
   422                                  TRequestStatus& aStatus)
       
   423    {	
       
   424    aStatus = KRequestPending;
       
   425    iClientStatus = &aStatus;
       
   426 	
       
   427    iOptionSelected = &aOptions;
       
   428    iFingerprint = &aFingerprint;
       
   429    aFingerprint = 0;
       
   430    iEvaluatorInfo = &aEvaluatorInfo;
       
   431    iClientStatus = &aStatus;
       
   432 	
       
   433    // Start state machine
       
   434    ASSERT(iState == EDisplayDialog); // PrepareDialog should have been called first
       
   435    iStatus = KRequestPending;
       
   436    TRequestStatus* status = &iStatus;
       
   437    SetActive();
       
   438    User::RequestComplete(status, KErrNone);
       
   439    }
       
   440