languageinterworkingfw/servicehandler/src/liwservicehandlerimpl.cpp
changeset 57 61b27eec6533
parent 45 7aa6007702af
equal deleted inserted replaced
45:7aa6007702af 57:61b27eec6533
     1 /*
       
     2 * Copyright (c) 2003-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:       Implements API for consumer application to access Language
       
    15 *                Interworking Framework. 
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 #include <eikenv.h>
       
    25 #include <bautils.h>    // file helpers
       
    26 #include <liwservicehandler.rsg>
       
    27 #include "liwmenubinding.h"
       
    28 #include "liwservicehandler.h"
       
    29 #include "liwservicehandlerimpl.h"
       
    30 #include "liwmenu.h"
       
    31 #include "liwuids.hrh"
       
    32 #include "liwcommon.hrh"
       
    33 #include "liwmenuslot.hrh"
       
    34 #include "liwecommonitor.h"
       
    35 #include "liwtlsdata.h"
       
    36 #include "data_caging_path_literals.hrh"
       
    37 
       
    38 #include "liwxmlhandler.h"
       
    39 #include "liwservicedata.h"
       
    40 
       
    41 #include <rtsecmgrscriptsession.h>
       
    42 
       
    43 // CONSTANTS
       
    44 // Max number of empty menu resource slots.
       
    45 const TInt KMaxMenuResources = 16;
       
    46 
       
    47 // This value tells how many times consumer can call InitializeMenuPaneL() without 
       
    48 // closing the Options-menu.
       
    49 const TInt KMaxPaneIds = KMaxMenuResources;
       
    50 
       
    51 // The range reserved for individual menu pane.
       
    52 const TInt KIndividualMenuPaneIdRange = 10000;
       
    53 
       
    54 // The whole range that is reserved to all menu panes. Currently value is 170 000.
       
    55 const TInt KMenuPaneCommandRange = (KMaxMenuResources + 1) * KIndividualMenuPaneIdRange; 
       
    56 
       
    57 _LIT(KLiwResourceFile, "liwServiceHandler.rsc");
       
    58 _LIT(KLiwZDrive, "z:");
       
    59 _LIT8(KDataSeparator, "||");
       
    60 _LIT(KPerExtension,".per");
       
    61 
       
    62 const TInt KMaxMenuTitleSize = 100;
       
    63 
       
    64 // Command id space reserved for single placeholder.
       
    65 const TInt KPlaceholderCmdIdRange = 200;
       
    66 
       
    67 const TInt KMaxLength=255;
       
    68 
       
    69 const TReal KDefVersion = 1.0;
       
    70 const TReal KUnspVersion = 0.0;
       
    71 
       
    72 void Cleanup(TAny* aAny);
       
    73 void InterestCleanup(TAny* aAny);
       
    74 void IntArrayCleanup(TAny* aAny);
       
    75 void FilteredCleanup(TAny* aAny);
       
    76 void Int32ArrayCleanup(TAny* aAny);
       
    77 void InterfaceCleanup(TAny* aAny);
       
    78 
       
    79 _LIT8(KResolverInterface, "IResolver");
       
    80 _LIT8(KResolverDomain, "ServiceManager");
       
    81 _LIT8(serviceCmdSeparator, "::");
       
    82 
       
    83 const TInt KDummySrvCmd=1;
       
    84 _LIT(KCapabilityCommDD,"CDD");
       
    85 _LIT(KCapabilityPowerMgmt,"PMT");
       
    86 _LIT(KCapabilityMultimediaDD,"MDD");
       
    87 _LIT(KCapabilityReadDeviceData,"RDD");
       
    88 _LIT(KCapabilityWriteDeviceData,"WDD");
       
    89 _LIT(KCapabilityDRM,"DRM");
       
    90 _LIT(KCapabilityTrustedUI,"TUI");
       
    91 _LIT(KCapabilityProtServ,"PSV");
       
    92 _LIT(KCapabilityDiskAdmin,"DAD");
       
    93 _LIT(KCapabilityNetworkControl,"NWC");
       
    94 _LIT(KCapabilityAllFiles,"ALF");
       
    95 _LIT(KCapabilitySwEvent,"SWE");
       
    96 _LIT(KCapabilityNetworkServices,"NWS");
       
    97 _LIT(KCapabilityLocalServices,"LOS");
       
    98 _LIT(KCapabilityReadUserData,"RUD");
       
    99 _LIT(KCapabilityWriteUserData,"WUD");
       
   100 _LIT(KCapabilityLocation,"LOC");
       
   101 _LIT(KCapabilitySurroundingsDD,"SDD");
       
   102 _LIT(KCapabilityUserEnvironment,"USE");
       
   103 
       
   104 using namespace LIW;
       
   105 //
       
   106 // LiwServiceHandler
       
   107 //
       
   108 
       
   109 CLiwServiceHandlerImpl* CLiwServiceHandlerImpl::NewL()
       
   110     {
       
   111     CLiwServiceHandlerImpl* handler = new (ELeave) CLiwServiceHandlerImpl();
       
   112     CleanupStack::PushL( handler );
       
   113     handler->ConstructL();
       
   114     CleanupStack::Pop(handler); // handler
       
   115     return handler;
       
   116     }
       
   117 
       
   118 
       
   119 
       
   120 CLiwServiceHandlerImpl::CLiwServiceHandlerImpl()
       
   121     {
       
   122     // Nothing to do here.
       
   123     }
       
   124 
       
   125 
       
   126 
       
   127 void CLiwServiceHandlerImpl::ConstructL()
       
   128     {
       
   129     TFileName resFile;
       
   130     TCallBack callBack(SynchronizeCallBack, this);
       
   131     iEcomMonitor = CLiwEcomMonitor::NewL(callBack);
       
   132 	
       
   133     
       
   134     iCoeEnv = CCoeEnv::Static();
       
   135     RFs rFs;
       
   136     TInt err = rFs.Connect();
       
   137     
       
   138     TFileName dllName;
       
   139     Dll::FileName(dllName);
       
   140 
       
   141     TBuf<2> drive = dllName.Left(2);
       
   142     resFile.Copy(drive);
       
   143     resFile.Append(KDC_RESOURCE_FILES_DIR);
       
   144     resFile.Append(KLiwResourceFile);	
       
   145     TBool fileExists( BaflUtils::FileExists(rFs, resFile) );
       
   146     if ( ! fileExists )
       
   147     {
       
   148 	resFile.Copy(KLiwZDrive);
       
   149 	resFile.Append(KDC_RESOURCE_FILES_DIR);
       
   150 	resFile.Append(KLiwResourceFile);
       
   151     }
       
   152     rFs.Close();
       
   153     // A Service Handler instance can be created also when CCoeEnv is not 
       
   154     // available (e.g. from server applications). In this case, the methods 
       
   155     // needing CCoeEnv/CEikonEnv will leave with KErrNotSupported.
       
   156     if(iCoeEnv)
       
   157         {
       
   158         // This is commented to avoid resource file getting locked affecting the IAD update. 
       
   159 	// Also, there is no use of resource file since LIW does not support menu related services
       
   160         // iResourceOffset = iCoeEnv->AddResourceFileL(resFile);
       
   161         }
       
   162     // CLiwTlsData has a reference count so each OpenL call
       
   163     // must have a matching Close call (done in destructor).
       
   164     // OpenL is called only here, the TLS data object can be
       
   165     // referenced by calling CLiwTlsData::Instance().
       
   166     CLiwTlsData* data = CLiwTlsData::OpenL();
       
   167     iTlsDataOpened = ETrue;
       
   168 
       
   169     // CEikMenuPane informs all menu launch observers
       
   170     // when an options menu is launched.
       
   171     data->AddMenuLaunchObserverL( this );
       
   172     }
       
   173 
       
   174 
       
   175 
       
   176 CLiwServiceHandlerImpl::~CLiwServiceHandlerImpl()
       
   177     {
       
   178     if (iResourceOffset && iCoeEnv)
       
   179         {
       
   180 	// This is commented to avoid resource file getting locked affecting the IAD update. 
       
   181 	// Also, there is no use of resource file since LIW does not support menu related services
       
   182         // iCoeEnv->DeleteResourceFile(iResourceOffset);
       
   183         }
       
   184     Reset();
       
   185 
       
   186     delete iEcomMonitor;
       
   187 
       
   188     if ( iTlsDataOpened )
       
   189         {
       
   190         CLiwTlsData* data = CLiwTlsData::Instance();
       
   191         data->RemoveMenuLaunchObserver( this );
       
   192         CLiwTlsData::Close();
       
   193         }
       
   194     }
       
   195 
       
   196 
       
   197 
       
   198 void CLiwServiceHandlerImpl::Reset()
       
   199     {
       
   200     iInterestList.ResetAndDestroy();
       
   201     iMenuBindings.ResetAndDestroy();
       
   202     iBaseBindings.ResetAndDestroy();
       
   203     iProviders.ResetAndDestroy();
       
   204 
       
   205     iLastInitialized.Reset();
       
   206 
       
   207     iMenuPanes.ResetAndDestroy();
       
   208 
       
   209     delete iInParams;
       
   210     iInParams = NULL;
       
   211     delete iOutParams;
       
   212     iOutParams = NULL;
       
   213     }
       
   214 
       
   215 void CLiwServiceHandlerImpl::AttachServiceManagerPluginsL()
       
   216 {
       
   217   CLiwCriteriaItem* crit = CLiwCriteriaItem::NewLC(KDummySrvCmd, KResolverInterface, KResolverDomain);
       
   218   crit->SetServiceClass(TUid::Uid(KLiwClassBase));
       
   219   
       
   220   RCriteriaArray a;
       
   221   a.AppendL(crit);
       
   222   
       
   223   AttachL(a);
       
   224   
       
   225   CleanupStack::Pop(crit); // crit
       
   226   a.ResetAndDestroy();
       
   227 }  
       
   228 
       
   229 void CLiwServiceHandlerImpl::ServiceManagerPlugin_ListImplementationsL(RArray<TInt32>& aArray,
       
   230                                                                        CLiwCriteriaItem* aItem)
       
   231 {
       
   232   CLiwGenericParamList* inps = &(InParamListL());
       
   233   CLiwGenericParamList* outps = &(OutParamListL());
       
   234   
       
   235   CLiwCriteriaItem* crit = CLiwCriteriaItem::NewLC(KDummySrvCmd, KResolverInterface, KResolverDomain);
       
   236   crit->SetServiceClass(TUid::Uid(KLiwClassBase));
       
   237 
       
   238   ExecuteServiceCmdL(*crit, *inps, *outps);  
       
   239   CleanupStack::PopAndDestroy(crit); // crit
       
   240 
       
   241   TInt pos = 0;
       
   242   MLiwInterface* ifp;
       
   243   const TLiwGenericParam* p = outps->FindFirst(pos, KResolverInterface, EVariantTypeInterface);
       
   244   if (p) {
       
   245     ifp = p->Value().AsInterface();
       
   246     CleanupStack::PushL(TCleanupItem(InterfaceCleanup, ifp));
       
   247   }
       
   248   else
       
   249     return;
       
   250   
       
   251   outps->Reset();
       
   252   inps->Reset();
       
   253   
       
   254   _LIT8(KId,"id");
       
   255   _LIT8(KCmd,"cmd");
       
   256   _LIT8(KCmdStr,"cmd_str");
       
   257   _LIT8(KType,"type");
       
   258   _LIT8(KListImpl,"ListImplementations");
       
   259   
       
   260   inps->AppendL(TLiwGenericParam(KId, TLiwVariant(aItem->Id())));
       
   261   inps->AppendL(TLiwGenericParam(KCmd, TLiwVariant(aItem->ServiceCmd())));
       
   262   inps->AppendL(TLiwGenericParam(KCmdStr, TLiwVariant(aItem->ServiceCmdStr())));
       
   263   inps->AppendL(TLiwGenericParam(KType, TLiwVariant(aItem->ContentType())));
       
   264   ifp->ExecuteCmdL(KListImpl, *inps, *outps);
       
   265   
       
   266   pos = 0;
       
   267   p = outps->FindFirst(pos, EGenericParamError);
       
   268   if (p && (p->Value().AsTInt32() == KErrNone)) {
       
   269     pos = 0;
       
   270     const CLiwList* list;
       
   271     _LIT8(KIdList,"id_list");
       
   272     p = outps->FindFirst(pos, KIdList, EVariantTypeList);
       
   273     if (p) {
       
   274       list = p->Value().AsList();
       
   275       for (TInt i = 0; i < list->Count(); i++) {
       
   276         TLiwVariant v;
       
   277         v.PushL();
       
   278         list->AtL(i, v);
       
   279         aArray.AppendL(v.AsTInt32());
       
   280         CleanupStack::Pop(&v);
       
   281         v.Reset();
       
   282       }
       
   283     }
       
   284   }
       
   285 
       
   286   CleanupStack::Pop(ifp); // ifp
       
   287   ifp->Close();
       
   288 }
       
   289 
       
   290 CLiwServiceIfBase* CLiwServiceHandlerImpl::ServiceManagerPlugin_CreateImplementationL(TInt32 aImplUid)
       
   291 {
       
   292   CLiwGenericParamList* inps = &(InParamListL());
       
   293   CLiwGenericParamList* outps = &(OutParamListL());
       
   294   
       
   295   CLiwCriteriaItem* crit = CLiwCriteriaItem::NewLC(KDummySrvCmd, KResolverInterface, KResolverDomain);
       
   296   crit->SetServiceClass(TUid::Uid(KLiwClassBase));
       
   297 
       
   298   ExecuteServiceCmdL(*crit, *inps, *outps);  
       
   299   CleanupStack::PopAndDestroy(crit); // crit
       
   300 
       
   301   TInt pos = 0;
       
   302   MLiwInterface* ifp = NULL;
       
   303   const TLiwGenericParam* p = outps->FindFirst(pos, KResolverInterface, EVariantTypeInterface);
       
   304   if (p) {
       
   305     ifp = p->Value().AsInterface();
       
   306     CleanupStack::PushL(TCleanupItem(InterfaceCleanup, ifp));
       
   307   }
       
   308   else
       
   309     User::Leave(KErrNotFound);
       
   310   
       
   311   outps->Reset();
       
   312   inps->Reset();
       
   313   _LIT8(KUid,"uid");
       
   314   _LIT8(KCreateImpl,"CreateImplementation");
       
   315   
       
   316   inps->AppendL(TLiwGenericParam(KUid, TLiwVariant(aImplUid)));
       
   317   ifp->ExecuteCmdL(KCreateImpl, *inps, *outps);
       
   318   
       
   319   pos = 0;
       
   320   p = outps->FindFirst(pos, EGenericParamError);
       
   321   User::LeaveIfError(p->Value().AsTInt32());
       
   322 
       
   323   pos = 0;
       
   324   CLiwServiceIfBase* iface = NULL;
       
   325   _LIT8(KImplPtr, "impl_ptr");
       
   326   p = outps->FindFirst(pos, KImplPtr, EVariantTypeDesC8);
       
   327   if (p) {
       
   328     TPtrC8 buf = p->Value().AsData();
       
   329     if (buf.Size() == sizeof(iface))
       
   330       Mem::Copy(&iface, buf.Ptr(), buf.Size());
       
   331     else
       
   332       User::Leave(KErrNotFound);
       
   333   }
       
   334   else
       
   335     User::Leave(KErrNotFound);
       
   336 
       
   337   CleanupStack::Pop(ifp); // ifp
       
   338   ifp->Close();
       
   339 
       
   340   return iface;
       
   341 }
       
   342 
       
   343 void CLiwServiceHandlerImpl::ListProvidersForCriteriaL(RArray<TInt>& aResult, 
       
   344     CLiwCriteriaItem& aItem)
       
   345     {
       
   346     TInt i;
       
   347 
       
   348     for (i = 0; i < iProviders.Count(); i++)
       
   349         {   
       
   350         if (iProviders[i]->HasCriteria(aItem))
       
   351             {
       
   352             User::LeaveIfError(aResult.Append(iProviders[i]->ImplementationUid().iUid));
       
   353             }
       
   354         }
       
   355     }
       
   356 
       
   357 
       
   358 
       
   359 TInt CLiwServiceHandlerImpl::NbrOfProviders(const CLiwCriteriaItem* aCriteria)
       
   360     {
       
   361     if(!aCriteria)
       
   362         {
       
   363         return 0;
       
   364         }
       
   365     
       
   366     TInt i, j;
       
   367 
       
   368     for (i = 0; i < iBaseBindings.Count(); i++)
       
   369         {
       
   370         for (j = 0; j < iBaseBindings[i]->Interest().Count(); j++)
       
   371             {
       
   372             if ((*iBaseBindings[i]->Interest()[j]) == (*aCriteria))
       
   373                 {
       
   374                 return iBaseBindings[i]->NumberOfProviders();
       
   375                 }
       
   376             }
       
   377         }
       
   378 
       
   379     for (i = 0; i < iMenuBindings.Count(); i++)
       
   380         {
       
   381         for (j = 0; j < iMenuBindings[i]->Interest().Count(); j++)
       
   382             {
       
   383             if ((*iMenuBindings[i]->Interest()[j]) == (*aCriteria))
       
   384                 {
       
   385                 return iMenuBindings[i]->NumberOfProviders();
       
   386                 }
       
   387             }       
       
   388         }
       
   389 
       
   390     return 0;
       
   391     }
       
   392 
       
   393 
       
   394 
       
   395 void CLiwServiceHandlerImpl::AttachL(TInt aInterestResourceId)
       
   396     {
       
   397     // CCoeEnv/CEikonEnv needs to be accessible.
       
   398     if(!iCoeEnv)
       
   399         {
       
   400         User::Leave(KErrNotSupported);
       
   401         }
       
   402     
       
   403     RCriteriaArray interest, filtered;
       
   404 
       
   405     CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) );
       
   406     CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) );
       
   407 
       
   408     TResourceReader reader;
       
   409     iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId);
       
   410     ReadInterestListL(reader, interest);
       
   411     CleanupStack::PopAndDestroy(); //reader
       
   412 
       
   413     FilterInterestListL(interest, filtered);
       
   414     
       
   415     DoAttachL(filtered,NULL);
       
   416 
       
   417     filtered.Reset();
       
   418 
       
   419     CleanupStack::Pop(&filtered); // filtered
       
   420     CleanupStack::Pop(&interest); // interest
       
   421     }
       
   422 
       
   423 
       
   424 
       
   425 TInt CLiwServiceHandlerImpl::AttachL(const RCriteriaArray& aInterest)
       
   426     {
       
   427     	return (this->AttachL(aInterest,NULL));
       
   428     }
       
   429 
       
   430 TInt CLiwServiceHandlerImpl::AttachL(const RCriteriaArray& aInterest ,CRTSecMgrScriptSession* aSecMgrScriptSession)
       
   431     {
       
   432     RCriteriaArray interest, filtered;
       
   433     
       
   434     CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) );
       
   435     CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) );
       
   436         
       
   437     for(TInt i = 0; i < aInterest.Count(); i++)
       
   438         {
       
   439         CLiwCriteriaItem* item = CLiwCriteriaItem::NewLC();
       
   440         	
       
   441         item->SetId(               aInterest[i]->Id()                    );
       
   442         if (aInterest[i]->ServiceCmd() == KLiwCmdAsStr)
       
   443           item->SetServiceCmdL(    aInterest[i]->ServiceCmdStr()         );
       
   444         else
       
   445           item->SetServiceCmd(     aInterest[i]->ServiceCmd()            );
       
   446         item->SetContentTypeL(     aInterest[i]->ContentType()           );
       
   447         item->SetServiceClass(     aInterest[i]->ServiceClass()          );
       
   448         
       
   449         item->SetOptions(          aInterest[i]->Options()               );
       
   450 		
       
   451 		//Setting the imetadataOptions of item
       
   452 		TLiwVariant metadataOption;
       
   453 		metadataOption.PushL();
       
   454 		
       
   455         aInterest[i]->GetMetaDataOptions(metadataOption);
       
   456 		item->SetMetaDataOptions(metadataOption);
       
   457 		metadataOption.Reset();
       
   458 				
       
   459         item->SetDefaultProvider( (aInterest[i]->DefaultProvider()).iUid );
       
   460         item->SetMaxProviders(     aInterest[i]->MaxProviders()          ); 
       
   461         
       
   462         User::LeaveIfError(interest.Append(item));
       
   463         CleanupStack::Pop(&metadataOption); 
       
   464         CleanupStack::Pop(item); 
       
   465         }
       
   466         
       
   467     FilterInterestListL(interest, filtered);        
       
   468 
       
   469 	TInt result = DoAttachL(filtered,aSecMgrScriptSession);
       
   470 
       
   471     filtered.Reset();
       
   472 		
       
   473     CleanupStack::Pop(&filtered); // filtered
       
   474     CleanupStack::Pop(&interest); // interest
       
   475     
       
   476     return result;
       
   477     }
       
   478 
       
   479 TInt CLiwServiceHandlerImpl::DoAttachL(const RCriteriaArray& aInterest,CRTSecMgrScriptSession* aSecMgrScriptSession)
       
   480     {
       
   481     CLiwBinding* bind;
       
   482     TInt success = -1;
       
   483     for (TInt i = 0; i < aInterest.Count(); i++)
       
   484         {
       
   485         bind = CLiwBinding::NewLC();
       
   486         
       
   487         success = ResolveProvidersL(bind, aInterest[i],aSecMgrScriptSession);
       
   488         
       
   489         if (success == KLiwServiceLoadSuccess)
       
   490             {
       
   491             User::LeaveIfError(iBaseBindings.Append( bind ));
       
   492             CleanupStack::Pop(bind); // bind
       
   493             bind->AddCriteriaL(aInterest[i]);
       
   494 
       
   495             // Initialise providers.
       
   496             for (TInt k = 0; k < bind->NumberOfProviders(); k++)
       
   497                 {
       
   498                 // Trap the initialisation. If not done, a leaving provider
       
   499                 // could prevent the initialisation of other providers.
       
   500                 TRAPD(err, bind->BaseProvider(k)->InitialiseL(*this, bind->Interest()));
       
   501                 
       
   502                 
       
   503                 
       
   504                 if(err)
       
   505                     {
       
   506 #ifdef _DEBUG                    
       
   507                     RDebug::Print(_L("LIW PROVIDER ERROR: CLiwServiceIfBase::InitialiseL() failed, leave code:%d"), err);
       
   508 #endif                    
       
   509                     }
       
   510                 }
       
   511             }
       
   512         else
       
   513             {
       
   514             CleanupStack::PopAndDestroy(bind); // bind
       
   515             }
       
   516         }
       
   517     	return success; // returns status of 'n'th criteria in interest
       
   518     }
       
   519 
       
   520 
       
   521 void CLiwServiceHandlerImpl::GetInterest(RCriteriaArray& aInterest)
       
   522     {
       
   523     for (TInt i = 0; i < iInterestList.Count(); i++)
       
   524         {
       
   525         if (aInterest.Append(iInterestList[i]) != KErrNone)
       
   526             {
       
   527             return;
       
   528             }
       
   529         }
       
   530     }
       
   531     
       
   532     
       
   533 
       
   534 void CLiwServiceHandlerImpl::DetachL(const RCriteriaArray& aInterest)
       
   535     {
       
   536     // First, remove relevant criteria items from relevat base bindings.
       
   537     for (TInt i = 0; i < aInterest.Count(); i++)
       
   538         {
       
   539         for (TInt j = 0; j < iBaseBindings.Count(); j++)
       
   540             {
       
   541             TInt index = iBaseBindings[j]->HasCriteriaItem(*aInterest[i]);
       
   542             if (index != KErrNotFound)
       
   543                 {
       
   544                 iBaseBindings[j]->RemoveCriteria(index);
       
   545                 }                           
       
   546             }
       
   547         }
       
   548 
       
   549     // Second pass removes empty bindings.
       
   550     for (TInt i = 0; i < iBaseBindings.Count(); i++)
       
   551         {
       
   552         if (iBaseBindings[i]->Interest().Count() == 0)
       
   553             {
       
   554             delete iBaseBindings[i];
       
   555             iBaseBindings.Remove(i);
       
   556             i--;
       
   557             }
       
   558         }
       
   559 
       
   560     // Then check if there were left obselete criteria items and remove them.   
       
   561     RemoveObsoleteCriteriaItems();
       
   562     
       
   563     // Finally check if there were left obselete providers and remove them.
       
   564     RemoveObsoleteProviders();        
       
   565     }
       
   566 
       
   567 
       
   568 
       
   569 void CLiwServiceHandlerImpl::DetachL(TInt aInterestResourceId)
       
   570     { 
       
   571     // CCoeEnv/CEikonEnv needs to be accessible.
       
   572     if(!iCoeEnv)
       
   573         {
       
   574         User::Leave(KErrNotSupported);
       
   575         }
       
   576     
       
   577     RCriteriaArray interest;
       
   578 
       
   579     CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) );
       
   580 
       
   581     TResourceReader reader;
       
   582     iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId);
       
   583     ReadInterestListL(reader, interest);
       
   584     CleanupStack::PopAndDestroy(); //reader
       
   585 
       
   586     DetachL( interest );
       
   587 
       
   588     interest.ResetAndDestroy();
       
   589     CleanupStack::Pop(&interest); // interest
       
   590     }
       
   591 
       
   592 
       
   593 const CLiwCriteriaItem* CLiwServiceHandlerImpl::GetCriteria(TInt aId)
       
   594     {
       
   595     for (TInt i = 0; i < iInterestList.Count(); i++)
       
   596         {
       
   597         if (iInterestList[i]->Id() == aId)
       
   598             {
       
   599             return iInterestList[i];
       
   600             }
       
   601         }
       
   602 
       
   603     return NULL;  
       
   604     }
       
   605     
       
   606 TInt CLiwServiceHandlerImpl::NumAlreadyInitializedPaneIdsL() const
       
   607     {
       
   608     TInt ret = 0;
       
   609     TInt paneIds[KMaxPaneIds] = {0};
       
   610     TBool found = EFalse;
       
   611     
       
   612     for (TInt i = 0; i < iLastInitialized.Count(); i++)
       
   613         {
       
   614         found = EFalse;
       
   615         
       
   616         for (TInt j = 0; j < ret; j++)
       
   617             {
       
   618             if (iLastInitialized[i]->MenuResourceId() == paneIds[j])
       
   619                 {
       
   620                 found = ETrue;
       
   621                 break;              
       
   622                 }
       
   623             }
       
   624                 
       
   625         if (!found) 
       
   626             {
       
   627             // Create new item.
       
   628             if (ret >= KMaxPaneIds)
       
   629                 {
       
   630 #ifdef _DEBUG
       
   631                 RDebug::Print(_L("ERROR: OVERFLOW in CLiwServiceHandlerImpl::NumAlreadyInitializedPaneIdsL()"));
       
   632 #endif
       
   633                 User::Leave(KErrOverflow);
       
   634                 }
       
   635             paneIds[ret] = iLastInitialized[i]->MenuResourceId();
       
   636             ret++;
       
   637             }                       
       
   638         }
       
   639     return ret;         
       
   640     }    
       
   641 
       
   642 void CLiwServiceHandlerImpl::InitializeMenuPaneL(
       
   643     CEikMenuPane& aMenuPane,
       
   644     TInt aMenuResourceId, 
       
   645     TInt aBaseMenuCmdId,
       
   646     const CLiwGenericParamList& aInParamList)
       
   647     {
       
   648     InitializeMenuPaneL(aMenuPane, aMenuResourceId, aBaseMenuCmdId, aInParamList, EFalse);    
       
   649     }        
       
   650         
       
   651 void CLiwServiceHandlerImpl::InitializeMenuPaneL(
       
   652     CEikMenuPane& aMenuPane,
       
   653     TInt aMenuResourceId, 
       
   654     TInt aBaseMenuCmdId,
       
   655     const CLiwGenericParamList& aInParamList,
       
   656     TBool aUseSubmenuTextsIfAvailable)
       
   657     {        
       
   658     // CCoeEnv/CEikonEnv needs to be accessible.
       
   659     if(!iCoeEnv)
       
   660         {
       
   661         User::Leave(KErrNotSupported);
       
   662         }
       
   663     
       
   664     if (!iMenuBindings.Count())
       
   665         {
       
   666         // Either no menu is attached to interest or menu was attached but
       
   667         // it didn't contain any placeholders for criteria items. So
       
   668         // nothing to do, get out.
       
   669         return;
       
   670         }
       
   671 
       
   672     TInt index;
       
   673     TInt slotcmd;
       
   674     TBuf <KMaxMenuTitleSize> subTitle;
       
   675     TBool titleLocked;
       
   676     TInt paneOffset = NumAlreadyInitializedPaneIdsL() * KIndividualMenuPaneIdRange;
       
   677 
       
   678     iSubmenuCmd = aBaseMenuCmdId + KMenuPaneCommandRange;
       
   679     slotcmd = SlotItemCmd(aMenuPane);
       
   680     if (slotcmd >= 0)
       
   681         {
       
   682         // aMenuPane is liw submenu. At this point it is empty and we must
       
   683         // copy provider menu items to it.
       
   684         CLiwMenuPane* liwPane = MenuPaneForSlotCmd(slotcmd);
       
   685         if (liwPane)
       
   686             {
       
   687             CopyMenuItemsL(liwPane, aMenuPane, 0, ETrue);
       
   688             aMenuPane.DeleteMenuItem(slotcmd);
       
   689             iSubmenu = liwPane;
       
   690             }
       
   691         }
       
   692     else
       
   693         {
       
   694         iSubmenu = NULL;
       
   695         
       
   696         const TInt bindcount = iMenuBindings.Count();
       
   697         for (TInt i = 0; i < bindcount; i++)
       
   698             {
       
   699             if  ((iMenuBindings[i]->MenuId() == aMenuResourceId) &&
       
   700                 (aMenuPane.MenuItemExists(iMenuBindings[i]->MenuCmd(), index)))
       
   701                 {
       
   702                 CLiwMenuPane* liwPane = iMenuBindings[i]->MenuPane();
       
   703                 TInt menuResourceId = -1;
       
   704                 if(liwPane)
       
   705                     {
       
   706                     // An LIW menu pane already exists (this means that a normal
       
   707                     // non-LIW submenu with LIW items has been opened more than once). 
       
   708                     // In this case we use the existing resource slot id.
       
   709                     menuResourceId = liwPane->ResourceSlotId();
       
   710                     paneOffset = liwPane->PaneOffset();
       
   711                     DeleteLiwMenuPane(liwPane);
       
   712                     liwPane = NULL;
       
   713                     }
       
   714                 liwPane = CreateEmptyLiwMenuPaneL(aBaseMenuCmdId, menuResourceId);
       
   715                 CleanupStack::PushL(liwPane);
       
   716                 liwPane->SetPaneOffset(paneOffset);
       
   717                 paneOffset += KPlaceholderCmdIdRange;
       
   718                 iMenuBindings[i]->SetMenuPane(liwPane);     
       
   719 
       
   720                 // Clean previous service commands from list.
       
   721                 CLiwGenericParamList& list = const_cast<CLiwGenericParamList&>(aInParamList);
       
   722                 while (list.Remove(EGenericParamServiceCommand)) 
       
   723                     {
       
   724                     // Intentionally left empty.    
       
   725                     }
       
   726 
       
   727                 // Add service commands for current placeholder.
       
   728                 const TInt icount = iMenuBindings[i]->Interest().Count();
       
   729                 for (TInt k = 0; k < icount; k++)
       
   730                     {
       
   731                     list.AppendL(TLiwGenericParam(EGenericParamServiceCommand,
       
   732                         TLiwVariant(iMenuBindings[i]->Interest()[k]->ServiceCmd())));
       
   733                     }
       
   734 
       
   735                 // Loop from last entry to first entry always inserting to same index.
       
   736                 // Default provider is the first item in list, so if there is a default
       
   737                 // provider defined, it will be the first one to appear in menus.               
       
   738                 for (TInt j = iMenuBindings[i]->NumberOfProviders() - 1; j >= 0; j--)
       
   739                     {
       
   740                     liwPane->SetInitializingOwner(iMenuBindings[i]->MenuProvider(j));
       
   741                     iMenuBindings[i]->MenuProvider(j)->InitializeMenuPaneHookL(liwPane,
       
   742                         0, 0, aInParamList);
       
   743                     }
       
   744 
       
   745                 GetSubmenuTitle(liwPane->MenuPane(), subTitle);
       
   746             
       
   747                 TLiwPlaceholderType phtype = PlaceholderType(aMenuPane, 
       
   748                     iMenuBindings[i]->MenuCmd(), titleLocked);
       
   749 
       
   750                 if ((phtype == ELiwPlaceholderCascade) ||
       
   751                     (phtype == ELiwPlaceholderIntelligentCascade))
       
   752                     {
       
   753                     if (liwPane->MenuPane().NumberOfItemsInPane() == 1)
       
   754                         {
       
   755                         // Remove placeholder item.
       
   756                         aMenuPane.DeleteMenuItem(iMenuBindings[i]->MenuCmd());
       
   757                         CleanupStack::PopAndDestroy(liwPane); // liwPane
       
   758                         continue;
       
   759                         }
       
   760                     else if ((liwPane->MenuPane().NumberOfItemsInPane() == 2) &&
       
   761                         (phtype == ELiwPlaceholderIntelligentCascade))
       
   762                         {
       
   763                         UnCascadeL(aMenuPane, iMenuBindings[i]->MenuCmd(), *liwPane);
       
   764                         User::LeaveIfError(iLastInitialized.Append(liwPane));
       
   765                         }
       
   766                     else
       
   767                         {
       
   768                         if (titleLocked)
       
   769                             {
       
   770                             subTitle.Zero();
       
   771                             }
       
   772                         ConvertPlaceholderL(aMenuPane, iMenuBindings[i]->MenuCmd(), *liwPane, 
       
   773                             subTitle);
       
   774                         }       
       
   775                     }
       
   776                 else
       
   777                     {
       
   778                     // Remove placeholder item.
       
   779                     aMenuPane.DeleteMenuItem(iMenuBindings[i]->MenuCmd());
       
   780         
       
   781                     // Copy menu items to actual menu pane
       
   782                     CopyMenuItemsL(liwPane, aMenuPane, index, aUseSubmenuTextsIfAvailable);
       
   783                     User::LeaveIfError(iLastInitialized.Append(liwPane));
       
   784                     }
       
   785                 liwPane->SetMenuResourceId(aMenuResourceId);
       
   786                 User::LeaveIfError(iMenuPanes.Append(liwPane));
       
   787                 CleanupStack::Pop(liwPane); // liwPane
       
   788                 }
       
   789             }
       
   790         }
       
   791     }
       
   792 
       
   793 
       
   794 
       
   795 
       
   796 TInt CLiwServiceHandlerImpl::ServiceCmdByMenuCmd(TInt aMenuCmdId) const
       
   797     {
       
   798     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
   799         {
       
   800         if ((IsInLastInitialized(iMenuBindings[i]->MenuPane())) &&
       
   801             (iMenuBindings[i]->MenuPane()->IsCmdInRange(KPlaceholderCmdIdRange, aMenuCmdId)))
       
   802             {
       
   803             return iMenuBindings[i]->MenuPane()->ServiceCmdId(aMenuCmdId); 
       
   804             }
       
   805         }
       
   806 
       
   807     return 0;   
       
   808     }
       
   809 
       
   810 
       
   811 
       
   812 void CLiwServiceHandlerImpl::ExecuteMenuCmdL(
       
   813     TInt aMenuCmdId,
       
   814     const CLiwGenericParamList& aInParamList,
       
   815     CLiwGenericParamList& aOutParamList,
       
   816     TUint aCmdOptions,
       
   817     MLiwNotifyCallback* aCallback)
       
   818     {
       
   819     // CCoeEnv/CEikonEnv needs to be accessible.
       
   820     if(!iCoeEnv)
       
   821         {
       
   822         User::Leave(KErrNotSupported);
       
   823         }
       
   824     
       
   825     if (!iMenuBindings.Count())
       
   826         {
       
   827         return;
       
   828         }   
       
   829 
       
   830     // Handle real menu providers.
       
   831     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
   832         {
       
   833         CLiwMenuPane* menuPane = iMenuBindings[i]->MenuPane();
       
   834 
       
   835         if (IsInLastInitialized(menuPane))
       
   836             {
       
   837             for (TInt j = 0; j < iMenuBindings[i]->NumberOfProviders(); j++)
       
   838                 {
       
   839                 if ((menuPane->IsCmdInRange(KPlaceholderCmdIdRange, aMenuCmdId)) && 
       
   840                     (menuPane->CommandOwner(aMenuCmdId) == iMenuBindings[i]->MenuProvider(j)))
       
   841                     {
       
   842                     iMenuBindings[i]->MenuProvider(j)->HandleMenuCmdHookL(
       
   843                         menuPane, 
       
   844                         aMenuCmdId, 
       
   845                         aInParamList, 
       
   846                         aOutParamList, 
       
   847                         aCmdOptions, 
       
   848                         aCallback); 
       
   849                     return;
       
   850                     }
       
   851                 }
       
   852             }
       
   853         }
       
   854     }
       
   855 
       
   856 
       
   857 
       
   858 void CLiwServiceHandlerImpl::AttachMenuL(TInt aMenuResourceId, TInt aInterestResourceId)
       
   859     {
       
   860     // CCoeEnv/CEikonEnv needs to be accessible.
       
   861     if(!iCoeEnv)
       
   862         {
       
   863         User::Leave(KErrNotSupported);
       
   864         }
       
   865     
       
   866     RCriteriaArray interest, filtered;
       
   867     TResourceReader reader;
       
   868 
       
   869     CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) );
       
   870     CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) );
       
   871     iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId);
       
   872     ReadInterestListL(reader, interest);
       
   873     CleanupStack::PopAndDestroy(); //reader
       
   874     FilterInterestListL(interest, filtered);
       
   875 
       
   876     iCoeEnv->CreateResourceReaderLC(reader, aMenuResourceId);
       
   877     DoAttachMenuL(reader, aMenuResourceId, filtered);
       
   878     filtered.Reset();
       
   879     CleanupStack::PopAndDestroy(); //reader
       
   880     CleanupStack::Pop(&filtered); // filtered
       
   881     CleanupStack::Pop(&interest); // interest
       
   882     }
       
   883 
       
   884 
       
   885 
       
   886 void CLiwServiceHandlerImpl::AttachMenuL(TInt aMenuResourceId, TResourceReader& aReader)
       
   887     {
       
   888     // CCoeEnv/CEikonEnv needs to be accessible.
       
   889     if(!iCoeEnv)
       
   890         {
       
   891         User::Leave(KErrNotSupported);
       
   892         }
       
   893     
       
   894     RCriteriaArray interest, filtered;
       
   895     TResourceReader reader;
       
   896 
       
   897     CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) );
       
   898     CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) );
       
   899     ReadInterestListL(aReader, interest);
       
   900     FilterInterestListL(interest, filtered);
       
   901 
       
   902     iCoeEnv->CreateResourceReaderLC(reader, aMenuResourceId);
       
   903     DoAttachMenuL(reader, aMenuResourceId, filtered);
       
   904     filtered.Reset();
       
   905     CleanupStack::PopAndDestroy(); //reader
       
   906     CleanupStack::Pop(&filtered); // filtered
       
   907     CleanupStack::Pop(&interest); // interest
       
   908     }
       
   909 
       
   910 void CLiwServiceHandlerImpl::AttachMenuL(TInt aMenuResourceId, const RCriteriaArray& aInterest)
       
   911     {
       
   912     // CCoeEnv/CEikonEnv needs to be accessible.
       
   913     if(!iCoeEnv)
       
   914         {
       
   915         User::Leave(KErrNotSupported);
       
   916         }    
       
   917     
       
   918     RCriteriaArray interest, filtered;
       
   919     TResourceReader reader;
       
   920     
       
   921     CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) );
       
   922     CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) );
       
   923         
       
   924     for(TInt i = 0; i < aInterest.Count(); i++)
       
   925         {
       
   926         CLiwCriteriaItem* item = CLiwCriteriaItem::NewLC();
       
   927         
       
   928         item->SetId(               aInterest[i]->Id()                    );
       
   929         item->SetServiceCmd(       aInterest[i]->ServiceCmd()            );
       
   930         item->SetContentTypeL(     aInterest[i]->ContentType()           );
       
   931         item->SetServiceClass(     aInterest[i]->ServiceClass()          );
       
   932         item->SetOptions(          aInterest[i]->Options()               );
       
   933         item->SetDefaultProvider( (aInterest[i]->DefaultProvider()).iUid );
       
   934         item->SetMaxProviders(     aInterest[i]->MaxProviders()          );       
       
   935         
       
   936         User::LeaveIfError(interest.Append(item));
       
   937         CleanupStack::Pop(item); 
       
   938         }
       
   939         
       
   940     FilterInterestListL(interest, filtered);        
       
   941 
       
   942     iCoeEnv->CreateResourceReaderLC(reader, aMenuResourceId);
       
   943     DoAttachMenuL(reader, aMenuResourceId, filtered);
       
   944     filtered.Reset();
       
   945     CleanupStack::PopAndDestroy(); //reader
       
   946     CleanupStack::Pop(&filtered); // filtered
       
   947     CleanupStack::Pop(&interest); // interest    
       
   948     }   
       
   949 
       
   950 void CLiwServiceHandlerImpl::AttachMenuL(RArray<TInt>& aMenuEntries,
       
   951                                          TInt aMenuResourceId,
       
   952                                          RCriteriaArray& aInterest)
       
   953     {
       
   954     RCriteriaArray filtered;
       
   955 
       
   956     CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) );
       
   957     FilterInterestListL(aInterest, filtered);
       
   958     
       
   959     TInt menuCmd;
       
   960     TInt count = aMenuEntries.Count();
       
   961     TBool bound;
       
   962 
       
   963     for (TInt i = 0; i < count; i++)
       
   964         {
       
   965         menuCmd = aMenuEntries[i];
       
   966         CLiwMenuBinding* bind = NULL;
       
   967         bound = EFalse;
       
   968 
       
   969         if (!menuCmd)
       
   970           continue;
       
   971 
       
   972         for (TInt j = 0; j < filtered.Count(); j++)
       
   973             {           
       
   974             if (filtered[j]->Id() == menuCmd)
       
   975                 {                       
       
   976                 if (!bind)
       
   977                     {
       
   978                     bind = AlreadyBound(aMenuResourceId, menuCmd, i);
       
   979                     if (!bind)
       
   980                         {
       
   981                         bind = CLiwMenuBinding::NewLC(i, aMenuResourceId);
       
   982                         bind->SetMenuCmd( menuCmd );
       
   983                         }
       
   984                     else
       
   985                         {
       
   986                         bound = ETrue;
       
   987                         }
       
   988                     }
       
   989                 
       
   990                 if (bind->HasCriteriaItem(*(filtered[j])) == KErrNotFound)
       
   991                     {
       
   992                     	ResolveProvidersL(bind, filtered[j],NULL);
       
   993                     bind->AddCriteriaL(filtered[j]);
       
   994                     }
       
   995                 }
       
   996             }
       
   997 
       
   998         // Initialise providers.
       
   999         if (bind)
       
  1000             {
       
  1001             for (TInt k = 0; k < bind->NumberOfProviders(); k++)
       
  1002                 {
       
  1003                 bind->MenuProvider(k)->InitialiseL(*this, bind->Interest());
       
  1004                 }
       
  1005             if (!bound)
       
  1006                 {
       
  1007                 User::LeaveIfError(iMenuBindings.Append( bind ));
       
  1008                 CleanupStack::Pop(bind);  // bind                       
       
  1009                 }
       
  1010             }
       
  1011         }
       
  1012 
       
  1013     filtered.Reset();
       
  1014     CleanupStack::Pop(&filtered); // filtered
       
  1015     }
       
  1016 
       
  1017 void CLiwServiceHandlerImpl::DoAttachMenuL(TResourceReader& aReader, TInt aMenuId, 
       
  1018     RCriteriaArray& aInterest)
       
  1019     {
       
  1020     TInt menuCmd;
       
  1021     TInt count = aReader.ReadInt16();
       
  1022     TBool bound;
       
  1023 
       
  1024     for (TInt i = 0; i < count; i++)
       
  1025         {
       
  1026         menuCmd = aReader.ReadInt32();
       
  1027         CLiwMenuBinding* bind = NULL;
       
  1028         bound = EFalse;
       
  1029 
       
  1030         for (TInt j = 0; j < aInterest.Count(); j++)
       
  1031             {           
       
  1032             if (aInterest[j]->Id() == menuCmd)
       
  1033                 {                       
       
  1034                 if (!bind)
       
  1035                     {
       
  1036                     bind = AlreadyBound(aMenuId, menuCmd, i);
       
  1037                     if (!bind)
       
  1038                         {
       
  1039                         bind = CLiwMenuBinding::NewLC(i, aMenuId);
       
  1040                         bind->SetMenuCmd( menuCmd );
       
  1041                         }
       
  1042                     else
       
  1043                         {
       
  1044                         bound = ETrue;
       
  1045                         }
       
  1046                     }
       
  1047                 
       
  1048                 if (bind->HasCriteriaItem(*(aInterest[j])) == KErrNotFound)
       
  1049                     {
       
  1050                     	ResolveProvidersL(bind, aInterest[j],NULL);
       
  1051                     bind->AddCriteriaL(aInterest[j]);
       
  1052                     }
       
  1053                 }
       
  1054             }
       
  1055 
       
  1056         // Initialise providers.
       
  1057         if (bind)
       
  1058             {
       
  1059             for (TInt k = 0; k < bind->NumberOfProviders(); k++)
       
  1060                 {
       
  1061                 TRAPD(err, bind->MenuProvider(k)->InitialiseL(*this, bind->Interest()));
       
  1062                 if(err)
       
  1063                     {
       
  1064 #ifdef _DEBUG
       
  1065                     RDebug::Print(_L("LIW PROVIDER ERROR: CLiwServiceIfMenu::InitialiseL() failed, leave code:%d"), err);
       
  1066 #endif                     
       
  1067                     // The provider failed to initialise.
       
  1068                     // Remove the failed provider from this menu binding.
       
  1069                     CLiwServiceIfMenu* provider = bind->MenuProvider(k);
       
  1070                     TInt implUid = provider->ImplementationUid().iUid;
       
  1071                     bind->RemoveProvider(implUid);
       
  1072                     
       
  1073                     // Remove the failed provider also from other menu bindings.
       
  1074                     for (TInt m = 0; m < iMenuBindings.Count(); m++)
       
  1075                         {
       
  1076                         iMenuBindings[m]->RemoveProvider(implUid);
       
  1077                         }
       
  1078 
       
  1079                     // Then remove provider from the owner list and delete it.
       
  1080                     for (TInt m = 0; m < iProviders.Count(); m++)
       
  1081                         {
       
  1082                         if (iProviders[m]->ImplementationUid().iUid == implUid)
       
  1083                             {
       
  1084                             delete iProviders[m];
       
  1085                             iProviders.Remove(m);
       
  1086                             m--;
       
  1087                             }
       
  1088                         }                    
       
  1089                     }
       
  1090                 }
       
  1091             if (!bound)
       
  1092                 {
       
  1093                 User::LeaveIfError(iMenuBindings.Append( bind ));
       
  1094                 CleanupStack::Pop(bind);  // bind                       
       
  1095                 }
       
  1096             }
       
  1097         SkipMenuFields(aReader);  // Jump to next menu item
       
  1098         }
       
  1099     }
       
  1100 
       
  1101 void CLiwServiceHandlerImpl::ReadInterestL(RCriteriaArray& aInterest, TInt aInterestResourceId)
       
  1102     {
       
  1103     CleanupStack::PushL( TCleanupItem( InterestCleanup, &aInterest ) );
       
  1104     TResourceReader reader;
       
  1105     iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId);
       
  1106     ReadInterestListL(reader, aInterest);
       
  1107     CleanupStack::PopAndDestroy(); //reader
       
  1108     CleanupStack::Pop(&aInterest);
       
  1109     }
       
  1110 
       
  1111 
       
  1112 void CLiwServiceHandlerImpl::DetachMenu(TInt aMenuResourceId, TInt aInterestResourceId)
       
  1113     {
       
  1114     // If interest resource id is null, then detach all items in the given menu.
       
  1115     if (!aInterestResourceId)
       
  1116         {
       
  1117         DoDetachMenu(aMenuResourceId);        
       
  1118         }
       
  1119     else
       
  1120         {
       
  1121         // CCoeEnv/CEikonEnv needs to be accessible.
       
  1122         if(!iCoeEnv)
       
  1123             {
       
  1124             // We cannot leave because this is a non-leaving method.
       
  1125             return; 
       
  1126             }    
       
  1127 
       
  1128         RCriteriaArray interest;
       
  1129         TRAPD(err, ReadInterestL(interest, aInterestResourceId));
       
  1130         if (err)
       
  1131             {
       
  1132             return;
       
  1133             }
       
  1134         
       
  1135         DoDetachMenu(aMenuResourceId, interest);
       
  1136         
       
  1137         interest.ResetAndDestroy();
       
  1138         }
       
  1139     }
       
  1140         
       
  1141 
       
  1142 void CLiwServiceHandlerImpl::DoDetachMenu(TInt aMenuResourceId)
       
  1143     {
       
  1144     // First, delete the relevant menu bindings.
       
  1145     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
  1146         {
       
  1147         if (iMenuBindings[i]->MenuId() == aMenuResourceId)
       
  1148             {
       
  1149             delete iMenuBindings[i];
       
  1150             iMenuBindings.Remove(i);
       
  1151             i--;
       
  1152             }
       
  1153         }
       
  1154 
       
  1155     // Then check if there were left obselete criteria items and remove them.   
       
  1156     RemoveObsoleteCriteriaItems();
       
  1157     
       
  1158     // Finally check if there were left obselete providers and remove them.
       
  1159     RemoveObsoleteProviders();  
       
  1160     }
       
  1161 
       
  1162     
       
  1163 void CLiwServiceHandlerImpl::DoDetachMenu(TInt aMenuResourceId, RCriteriaArray& aInterest)
       
  1164     {
       
  1165     // First, remove relevant criteria items from relevant menu bindings.
       
  1166     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
  1167         {
       
  1168         if (iMenuBindings[i]->MenuId() == aMenuResourceId) 
       
  1169             {
       
  1170             for (TInt j = 0; j < aInterest.Count(); j++)
       
  1171                 {
       
  1172                 TInt index = iMenuBindings[i]->HasCriteriaItem(*aInterest[j]);
       
  1173                 if (index != KErrNotFound)
       
  1174                     {
       
  1175                     iMenuBindings[i]->RemoveCriteria(index);
       
  1176                     }
       
  1177                 }
       
  1178             }
       
  1179         }
       
  1180 
       
  1181     // Second pass removes empty bindings.
       
  1182     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
  1183         {
       
  1184         if (iMenuBindings[i]->Interest().Count() == 0)
       
  1185             {
       
  1186             delete iMenuBindings[i];
       
  1187             iMenuBindings.Remove(i);
       
  1188             i--;
       
  1189             }
       
  1190         }
       
  1191     
       
  1192     // Then check if there were left obselete criteria items and remove them.   
       
  1193     RemoveObsoleteCriteriaItems();
       
  1194     
       
  1195     // Finally check if there were left obselete providers and remove them.
       
  1196     RemoveObsoleteProviders();        
       
  1197     }    
       
  1198     
       
  1199     
       
  1200 void CLiwServiceHandlerImpl::RemoveObsoleteCriteriaItems()
       
  1201     {
       
  1202     for (TInt i = 0; i < iInterestList.Count(); i++)
       
  1203         {
       
  1204         CLiwCriteriaItem* criteria = iInterestList[i];
       
  1205         TBool found = EFalse;
       
  1206         
       
  1207         // Loop through base bindings.
       
  1208         for (TInt j = 0; j < iBaseBindings.Count(); j++)
       
  1209             {
       
  1210             if (iBaseBindings[j]->HasCriteriaItem(*criteria) != KErrNotFound)
       
  1211                 {
       
  1212                 found = ETrue;
       
  1213                 break;
       
  1214                 }
       
  1215             }
       
  1216 
       
  1217         // If still not found, loop through menu bindings.        
       
  1218         if (!found)
       
  1219             {
       
  1220             for (TInt j = 0; j < iMenuBindings.Count(); j++)
       
  1221                 {
       
  1222                 if (iMenuBindings[j]->HasCriteriaItem(*criteria) != KErrNotFound)
       
  1223                     {
       
  1224                     found = ETrue;
       
  1225                     break;
       
  1226                     }
       
  1227                 }            
       
  1228             }
       
  1229             
       
  1230         // Criteria item can be deleted if it was not found.            
       
  1231         if (!found)
       
  1232             {
       
  1233             delete iInterestList[i];
       
  1234             iInterestList.Remove(i);
       
  1235             i--;
       
  1236             }
       
  1237         }    
       
  1238     }
       
  1239     
       
  1240     
       
  1241 void CLiwServiceHandlerImpl::RemoveObsoleteProviders()
       
  1242     {
       
  1243     for (TInt i = 0; i < iProviders.Count(); i++)
       
  1244         {
       
  1245         CLiwServiceIfBase* provider = iProviders[i];
       
  1246         TBool found = EFalse;
       
  1247         
       
  1248         // Loop through base bindings.
       
  1249         for (TInt j = 0; j < iBaseBindings.Count(); j++)
       
  1250             {
       
  1251             if (iBaseBindings[j]->HasProvider(provider))
       
  1252                 {
       
  1253                 found = ETrue;
       
  1254                 break;
       
  1255                 }
       
  1256             }
       
  1257 
       
  1258         // If still not found, loop through menu bindings.        
       
  1259         if (!found)
       
  1260             {
       
  1261             for (TInt j = 0; j < iMenuBindings.Count(); j++)
       
  1262                 {
       
  1263                 if (iMenuBindings[j]->HasProvider(provider))
       
  1264                     {
       
  1265                     found = ETrue;
       
  1266                     break;
       
  1267                     }
       
  1268                 }            
       
  1269             }
       
  1270             
       
  1271         // Criteria item can be deleted if it was not found.            
       
  1272         if (!found)
       
  1273             {
       
  1274             delete iProviders[i];
       
  1275             iProviders.Remove(i);
       
  1276             i--;
       
  1277             }
       
  1278         }    
       
  1279     }
       
  1280 
       
  1281 
       
  1282 TBool CLiwServiceHandlerImpl::IsSubMenuEmpty(TInt aSubMenuId)
       
  1283     {
       
  1284     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
  1285         {
       
  1286         if (iMenuBindings[i]->MenuId() == aSubMenuId)
       
  1287             {
       
  1288             if (iMenuBindings[i]->NumberOfProviders() > 0)
       
  1289                 {
       
  1290                 return EFalse;
       
  1291                 }
       
  1292 
       
  1293             return ETrue;
       
  1294             }
       
  1295         }
       
  1296 
       
  1297     return EFalse;
       
  1298     }
       
  1299 
       
  1300 
       
  1301 
       
  1302 
       
  1303 CLiwMenuBinding* CLiwServiceHandlerImpl::AlreadyBound(TInt aMenuId, TInt aMenuCmd, 
       
  1304     TInt aMenuItemIndex) const
       
  1305     {
       
  1306     for (TInt i = 0; i < iMenuBindings.Count(); i++)
       
  1307         {
       
  1308         if ((iMenuBindings[i]->MenuId() == aMenuId) &&
       
  1309             (iMenuBindings[i]->MenuCmd() == aMenuCmd) &&
       
  1310             (iMenuBindings[i]->MenuItemIndex() == aMenuItemIndex))
       
  1311             {
       
  1312             return iMenuBindings[i];
       
  1313             }
       
  1314         }
       
  1315 
       
  1316     return NULL;
       
  1317     }
       
  1318 
       
  1319 
       
  1320 void CLiwServiceHandlerImpl::ExecuteServiceCmdL(
       
  1321     const TInt& aCmdId,
       
  1322     const CLiwGenericParamList& aInParamList,
       
  1323     CLiwGenericParamList& aOutParamList,
       
  1324     TUint aCmdOptions,
       
  1325     MLiwNotifyCallback* aCallback)
       
  1326     {
       
  1327     for (TInt i = 0; i < iBaseBindings.Count(); i++)
       
  1328         {
       
  1329         if(iBaseBindings[i]->HasServiceCmd(aCmdId))
       
  1330             {
       
  1331         for (TInt j = 0; j < iBaseBindings[i]->NumberOfProviders(); j++)
       
  1332             {
       
  1333             iBaseBindings[i]->BaseProvider(j)->HandleServiceCmdL(aCmdId,
       
  1334                             aInParamList, aOutParamList, aCmdOptions, aCallback);
       
  1335             }
       
  1336         }
       
  1337 	}
       
  1338 }
       
  1339 
       
  1340 void CLiwServiceHandlerImpl::ExecuteServiceCmdL(    
       
  1341         const CLiwCriteriaItem& aCmd,
       
  1342         const CLiwGenericParamList& aInParamList,
       
  1343         CLiwGenericParamList& aOutParamList,
       
  1344         TUint aCmdOptions,
       
  1345         MLiwNotifyCallback* aCallback)
       
  1346     {
       
  1347       for (TInt i = 0; i < iBaseBindings.Count(); i++) {
       
  1348         for (TInt k = 0; k < iBaseBindings[i]->Interest().Count(); k++) {
       
  1349           if ((iBaseBindings[i]->Interest()[k]->ServiceCmd() == KLiwCmdAsStr) &&
       
  1350               (aCmd.ServiceCmd() == KLiwCmdAsStr) &&
       
  1351               (iBaseBindings[i]->Interest()[k]->ServiceCmdStr() == aCmd.ServiceCmdStr()) &&
       
  1352               (iBaseBindings[i]->Interest()[k]->ContentType() == aCmd.ContentType()))
       
  1353             {
       
  1354               //call only one provider
       
  1355               if (iBaseBindings[i]->NumberOfProviders() > 0) {
       
  1356                 iBaseBindings[i]->BaseProvider(0)->HandleServiceCmdL(aCmd.ServiceCmdStr(),
       
  1357                   aInParamList, aOutParamList, aCmdOptions, aCallback);
       
  1358               }
       
  1359             }
       
  1360         }
       
  1361       }
       
  1362     }
       
  1363 
       
  1364 void CLiwServiceHandlerImpl::ReadInterestListL(TResourceReader& aReader, 
       
  1365     RPointerArray<CLiwCriteriaItem>& aResult)  
       
  1366     {
       
  1367     const TInt count = aReader.ReadInt16();
       
  1368     for (TInt ii = 0; ii < count; ++ii)
       
  1369         {
       
  1370         CLiwCriteriaItem* item = CLiwCriteriaItem::NewLC();
       
  1371         item->ReadFromResoureL( aReader );
       
  1372         User::LeaveIfError(aResult.Append(item));
       
  1373         CleanupStack::Pop(item); // item
       
  1374         }
       
  1375     }
       
  1376 
       
  1377 /* Parses the metadata information stored in the opaque_data field
       
  1378  * of service provider registration information \c REGISTRY_INFO.
       
  1379  *
       
  1380  * The metadata information is seprated from the service command definition 
       
  1381  * in the opaque_data field using a separator "::".
       
  1382  *
       
  1383  * @param aOpaque	the opaque_data values specified in the registration information
       
  1384  * @param aMetaData the parsed metadata entries will be stored in this variable
       
  1385  * 
       
  1386  */
       
  1387 void CLiwServiceHandlerImpl::ParseMetaData(const TDesC8& aOpaque, TDes8& aMetaData)
       
  1388     {
       
  1389     
       
  1390        _LIT8(serviceCmdSeparator, "::");
       
  1391        const TInt metaDataStartPos=2;
       
  1392        
       
  1393        TInt separatorPos = aOpaque.Find(serviceCmdSeparator);
       
  1394         
       
  1395         if (separatorPos != KErrNotFound)
       
  1396         {
       
  1397         	// Find the first section, up to the separator
       
  1398         	separatorPos += metaDataStartPos;
       
  1399         	aMetaData.Copy(aOpaque.Mid(separatorPos,aOpaque.Length()-separatorPos));        
       
  1400         }
       
  1401     }
       
  1402 
       
  1403 /* 
       
  1404 	QueryImplementationL finds the providers that match the given criteria item that is passed as the parameters
       
  1405 */
       
  1406 void CLiwServiceHandlerImpl::QueryImplementationL(CLiwCriteriaItem* aItem, RCriteriaArray& aProviderList)
       
  1407 	{
       
  1408     RImplInfoPtrArray infoArray;
       
  1409 	_LIT8(KWild,"*");
       
  1410 
       
  1411     if(0 == aItem->ContentType().Compare(KNullDesC8))
       
  1412     	aItem->SetContentTypeL(KWild);
       
  1413     
       
  1414 	if(0 == aItem->ServiceCmdStr().Compare(KNullDesC8))
       
  1415 		aItem->SetServiceCmdL(KWild);
       
  1416     
       
  1417     //to fetch the infoArray
       
  1418     QueryImplementationL(aItem,infoArray);
       
  1419     
       
  1420    	CLiwXmlHandler* pXmlHandler = CLiwXmlHandler::NewLC();
       
  1421 		
       
  1422 	CLiwServiceData* pServiceData = NULL;
       
  1423 	
       
  1424 	TInt versionCheck = 0;
       
  1425 	
       
  1426 	for (TInt index = 0; index < infoArray.Count(); ++index)
       
  1427     	{
       
  1428         if ((aItem->Options() & LIW_OPTIONS_ROM_ONLY) && (infoArray[index]->RomBased() == EFalse))
       
  1429            	{
       
  1430             continue;
       
  1431             }
       
  1432 
       
  1433 		CImplementationInformation* pImplInfo = infoArray[index];
       
  1434 		const TInt separatorLength = KDataSeparator().Length();//find "||"		
       
  1435 		TInt separatorPos = pImplInfo->OpaqueData().Find(KDataSeparator);
       
  1436 		
       
  1437 		TInt leftExtractPos = 0;
       
  1438 		TBool separatorFound = EFalse;
       
  1439 		
       
  1440 		do
       
  1441 		{
       
  1442 			//Constructing the Criteria Item and appending to providerList
       
  1443 			CLiwCriteriaItem* item = CLiwCriteriaItem::NewLC(); //iCriteriaId & iServiceCmd are ignored...
       
  1444 			item->SetServiceClass(TUid::Uid(KLiwClassBase));
       
  1445 			item->SetContentTypeL(infoArray[index]->DataType());
       
  1446 			
       
  1447 			TBuf8<KMaxLength> sName;    		
       
  1448 			TBuf8<KMaxLength> opaq;
       
  1449 			
       
  1450 			if(separatorPos != KErrNotFound && (leftExtractPos < separatorPos))
       
  1451 			{
       
  1452 				separatorFound = ETrue;
       
  1453 				sName = pImplInfo->OpaqueData().Mid(leftExtractPos, separatorPos-leftExtractPos); //ServiceName					
       
  1454 				leftExtractPos = separatorLength + separatorPos;
       
  1455 		 	 	TPtrC8 remainingData = pImplInfo->OpaqueData().Mid(separatorPos + separatorLength);	
       
  1456         	 	separatorPos = remainingData.Find(KDataSeparator) + separatorPos + separatorLength;	
       
  1457 			}
       
  1458 			else
       
  1459 			{
       
  1460 				separatorFound = EFalse;
       
  1461 				TInt mDataSepPos = pImplInfo->OpaqueData().Find(serviceCmdSeparator);
       
  1462 				if(mDataSepPos != KErrNotFound)
       
  1463 					sName = pImplInfo->OpaqueData().Mid(leftExtractPos, mDataSepPos - leftExtractPos);
       
  1464 				else
       
  1465 					sName = pImplInfo->OpaqueData().Mid(leftExtractPos);
       
  1466 			}
       
  1467 
       
  1468 		   	//check for wildcard character *
       
  1469 		   	//if yes, return immediatly
       
  1470 			if(0 == aItem->ServiceCmdStr().Compare(sName) || 0 == aItem->ServiceCmdStr().Compare(KWild))
       
  1471 			{
       
  1472 				//parse metadata and if metadata valid,
       
  1473 				//setmetadataoptions to criteriaitem..
       
  1474 				pServiceData = CLiwServiceData::NewLC();  
       
  1475 				TInt loadStatus = CLiwXmlHandler::ESrvDataLoadFailed;
       
  1476 				
       
  1477 				ParseMetaData(pImplInfo->OpaqueData(),opaq);
       
  1478 				
       
  1479 				//Inline metadata defined
       
  1480 				if(opaq.Length()>0)
       
  1481 				{
       
  1482 					loadStatus=pXmlHandler->LoadServiceData(opaq,pServiceData);
       
  1483 				}
       
  1484 				else
       
  1485 				{
       
  1486 					//Obtain the capabilities from the metadata
       
  1487 		    		TUid implUid = pImplInfo->ImplementationUid();  
       
  1488 		    		TUidName srvProvUid = implUid.Name();        
       
  1489 		    		
       
  1490 		    		TPtrC16 ptrSrv = srvProvUid.Right(srvProvUid.Length()-1);      
       
  1491 		    		TPtrC16 srvFile = ptrSrv.Left(ptrSrv.Length()-1);		       
       
  1492 		    		TDriveUnit driveUnit = pImplInfo->Drive();
       
  1493 		    		TFileName fileName = driveUnit.Name();
       
  1494 		    		fileName.Append(KDC_RESOURCE_FILES_DIR);
       
  1495 		    		fileName.Append(srvFile);
       
  1496 		    		fileName.Append(KPerExtension);
       
  1497 		    		loadStatus=pXmlHandler->LoadServiceData(fileName,pServiceData);
       
  1498 				}
       
  1499 				
       
  1500 				if(CLiwXmlHandler::ESrvDataLoadSuccess==loadStatus)
       
  1501 				{	    		
       
  1502 					versionCheck = 0;
       
  1503 					
       
  1504 	    			TReal implVersion(KDefVersion);
       
  1505 	    			this->ComputeIntfVersion(pServiceData,implVersion); //fetch impl version..
       
  1506 	    			
       
  1507 	    			TReal minVer(KDefVersion);
       
  1508 	    			TReal maxVer(KUnspVersion);
       
  1509 	    			
       
  1510 	    			if(this->GetVersionRange(aItem,minVer,maxVer)) //Get version queried by consumer
       
  1511 	    			{
       
  1512 	    				if(minVer == KUnspVersion)
       
  1513 	    					minVer = KDefVersion;
       
  1514 	    				
       
  1515 	    				//perform comparison...
       
  1516     					if(maxVer!=KUnspVersion)
       
  1517     					{
       
  1518 	    					if((implVersion>=minVer) && (implVersion<=maxVer))
       
  1519 	    					{
       
  1520 	    						versionCheck = 1;
       
  1521 	    						//current impl is the best choice..this is THE CHOSEN ONE..
       
  1522 	    					}
       
  1523     					}
       
  1524     					else
       
  1525     					{
       
  1526     						//means maxVer == KUnspVersion
       
  1527     						if(implVersion>=minVer)
       
  1528 	    					{
       
  1529 	    						versionCheck = 1;
       
  1530 	    						
       
  1531 	    						//current impl is the best choice..this is THE CHOSEN ONE..
       
  1532 	    				 	}
       
  1533     					}
       
  1534 					}
       
  1535 				}
       
  1536 				else //means no metadata information
       
  1537 				{
       
  1538 					versionCheck = 1;
       
  1539 				}
       
  1540 				 
       
  1541 				if(versionCheck) 
       
  1542 				{
       
  1543 					//Since version matches, this item is appended to the providerList
       
  1544 					//before which the metadata information is SET
       
  1545 					CLiwMap* metadataMap = CLiwDefaultMap::NewLC();
       
  1546 					
       
  1547 					CLiwGenericParamList* pMetaData = pServiceData->GetMetaData();    					
       
  1548 					
       
  1549 					for(TInt mdataIdx(0); mdataIdx<pMetaData->Count(); ++mdataIdx)
       
  1550 					{
       
  1551 					    TLiwGenericParam param;	    			    
       
  1552 						pMetaData->AtL(mdataIdx,param);						
       
  1553 						metadataMap->InsertL(param.Name(),param.Value());						
       
  1554 						param.Reset();
       
  1555 					}
       
  1556 										
       
  1557 					TLiwVariant mdataVar(metadataMap);
       
  1558 					mdataVar.PushL();
       
  1559 					
       
  1560 					item->SetMetaDataOptions(mdataVar);
       
  1561 					
       
  1562 					item->SetServiceCmdL(sName);
       
  1563 					CleanupStack::Pop(&mdataVar);
       
  1564 					mdataVar.Reset();
       
  1565 					
       
  1566 					CleanupStack::Pop(metadataMap);
       
  1567 					metadataMap->DecRef();
       
  1568 					                     
       
  1569 					User::LeaveIfError(aProviderList.Append(item));
       
  1570 				}
       
  1571 				
       
  1572 				if(pServiceData)
       
  1573 				 		pServiceData->CleanUpMetaData();
       
  1574 				
       
  1575 				CleanupStack::PopAndDestroy(pServiceData); //pServiceData::CLiwServiceData*
       
  1576 				CleanupStack::Pop(item); //item::CLiwCriteriaItem*
       
  1577 			}
       
  1578 			else
       
  1579 			{
       
  1580 				CleanupStack::PopAndDestroy(item); //item::CLiwCriteriaItem*
       
  1581 			}
       
  1582 		}while(separatorFound);
       
  1583 	}// end of outer for loop
       
  1584 
       
  1585     CleanupStack::PopAndDestroy(pXmlHandler); //pXmlHandler::CLiwXMLHandler*
       
  1586     infoArray.ResetAndDestroy();
       
  1587 	}
       
  1588 
       
  1589 
       
  1590 void CLiwServiceHandlerImpl::QueryImplementationL(CLiwCriteriaItem* aItem, RImplInfoPtrArray& infoArray)
       
  1591 	{
       
  1592 	iEcomMonitor->ListImplemetationsL(infoArray, (CLiwCriteriaItem*)aItem);
       
  1593 	}
       
  1594 
       
  1595 
       
  1596 void CLiwServiceHandlerImpl::FilterInfoArray(RImplInfoPtrArray& aArray,
       
  1597                                              RArray<TInt32>& aArrayPlugin,
       
  1598                                              CLiwCriteriaItem* aItem)
       
  1599     {
       
  1600     if (aItem->MaxProviders() <= 0)
       
  1601         {
       
  1602         aArray.ResetAndDestroy();
       
  1603         aArrayPlugin.Reset();
       
  1604         }
       
  1605     else
       
  1606         {
       
  1607         while ((aArray.Count() + aArrayPlugin.Count()) > aItem->MaxProviders())
       
  1608             {
       
  1609             if (aArrayPlugin.Count() == 0)
       
  1610               break;
       
  1611             // Skip default provider.
       
  1612             if (aArrayPlugin[0] == aItem->DefaultProvider())
       
  1613                 {
       
  1614                 if (aArrayPlugin.Count() == 1)
       
  1615                   break;
       
  1616                 aArrayPlugin.Remove(1);
       
  1617                 }
       
  1618             else
       
  1619                 {
       
  1620                 aArrayPlugin.Remove(0);               
       
  1621                 }
       
  1622             }
       
  1623 
       
  1624         while ((aArray.Count() + aArrayPlugin.Count()) > aItem->MaxProviders())
       
  1625             {
       
  1626             // Skip default provider.
       
  1627             if (aArray[0]->ImplementationUid() == aItem->DefaultProvider())
       
  1628                 {
       
  1629                 delete aArray[1];
       
  1630                 aArray.Remove(1);               
       
  1631                 }
       
  1632             else
       
  1633                 {
       
  1634                 delete aArray[0];
       
  1635                 aArray.Remove(0);               
       
  1636                 }
       
  1637             }
       
  1638         }
       
  1639     }
       
  1640 
       
  1641 
       
  1642 
       
  1643 TBool CLiwServiceHandlerImpl::IsCached(CLiwServiceIfBase* /*aProvider*/)
       
  1644     {
       
  1645     return EFalse;
       
  1646     }
       
  1647 
       
  1648 
       
  1649 CLiwGenericParamList& CLiwServiceHandlerImpl::InParamListL()
       
  1650     {
       
  1651     if (!iInParams)
       
  1652         {
       
  1653         iInParams = CLiwGenericParamList::NewL();
       
  1654         }
       
  1655     iInParams->Reset();
       
  1656     return *iInParams;
       
  1657     }
       
  1658 
       
  1659 
       
  1660 
       
  1661 CLiwGenericParamList& CLiwServiceHandlerImpl::OutParamListL()
       
  1662     {
       
  1663     if (!iOutParams)
       
  1664         {
       
  1665         iOutParams = CLiwGenericParamList::NewL();
       
  1666         }
       
  1667     iOutParams->Reset();
       
  1668     return *iOutParams;
       
  1669     }
       
  1670 
       
  1671 
       
  1672 
       
  1673 TBool CLiwServiceHandlerImpl::IsInLastInitialized(CLiwMenuPane* liwPane) const
       
  1674     {
       
  1675     if (liwPane)
       
  1676         {
       
  1677         if (iSubmenu == liwPane)
       
  1678             {
       
  1679             return ETrue;       
       
  1680             }
       
  1681 
       
  1682         for (TInt i = 0; i < iLastInitialized.Count(); i++)
       
  1683             {
       
  1684             if (iLastInitialized[i] == liwPane)
       
  1685                 {
       
  1686                 return ETrue;
       
  1687                 }
       
  1688             }
       
  1689         }
       
  1690 
       
  1691     return EFalse;
       
  1692     }
       
  1693 
       
  1694 
       
  1695 TInt CLiwServiceHandlerImpl::HandleNotifyL(
       
  1696     TInt /*aCmdId*/,
       
  1697     TInt /*aEventId*/,
       
  1698     CLiwGenericParamList& /*aEventParamList*/,
       
  1699     const CLiwGenericParamList& /*aInParamList*/)
       
  1700     {
       
  1701     return KErrNone;    
       
  1702     }
       
  1703 
       
  1704 
       
  1705 // CEikMenuPane::ConstructFromresourceL is defined as 'protected' so
       
  1706 // we have to use a wrapper class for accessing it.
       
  1707 class CLiwMenuResource : public CEikMenuPane
       
  1708     {
       
  1709     public:
       
  1710         CLiwMenuResource() : CEikMenuPane(NULL) {}
       
  1711         CLiwMenuResource(MEikMenuObserver* aObserver) : CEikMenuPane(aObserver) {}
       
  1712 
       
  1713         void CreateL(TResourceReader& aReader)
       
  1714             {
       
  1715             ConstructFromResourceL(aReader);
       
  1716             }
       
  1717     };
       
  1718 
       
  1719 
       
  1720 CLiwMenuPane* CLiwServiceHandlerImpl::CreateEmptyLiwMenuPaneL(TInt aBaseMenuCmdId, 
       
  1721     TInt aResourceId)
       
  1722     {
       
  1723     CLiwMenuPane* result = NULL;
       
  1724     TResourceReader reader; 
       
  1725     
       
  1726     TInt id;
       
  1727     if(aResourceId >= 0)
       
  1728         {
       
  1729         // Use existing id.
       
  1730         id = aResourceId;
       
  1731         }
       
  1732     else
       
  1733         {
       
  1734         // Create new id.
       
  1735         id = ResourceIdForNextFreeSlot();
       
  1736         if (id < 0)
       
  1737             {
       
  1738             User::Leave(KErrOverflow);
       
  1739             }
       
  1740         }
       
  1741     iCoeEnv->CreateResourceReaderLC(reader, id);
       
  1742     
       
  1743     CLiwMenuResource* pane = new (ELeave) CLiwMenuResource(this);
       
  1744     CleanupStack::PushL(pane);
       
  1745     pane->ConstructL(NULL);
       
  1746     pane->CreateL(reader);
       
  1747 
       
  1748     result = new (ELeave) CLiwMenuPane(*pane, aBaseMenuCmdId);
       
  1749     
       
  1750     CleanupStack::Pop(pane);
       
  1751     CleanupStack::PopAndDestroy(); //reader
       
  1752     
       
  1753     result->SetResourceSlotId( id );
       
  1754     
       
  1755     return result;
       
  1756     }
       
  1757 
       
  1758 
       
  1759 void CLiwServiceHandlerImpl::DeleteLiwMenuPane(CLiwMenuPane* aLiwPane)
       
  1760     {
       
  1761     delete aLiwPane->iMenuPane;
       
  1762     aLiwPane->iMenuPane = NULL;
       
  1763 
       
  1764     // Reset iIdMap and extraText.
       
  1765     for(TInt i = 0; i < aLiwPane->iIdMap.Count(); i++)
       
  1766         {
       
  1767         aLiwPane->iIdMap[i].extraText.Close();
       
  1768         }
       
  1769     aLiwPane->iIdMap.Reset();
       
  1770     
       
  1771     // Remove the liw menu pane from iMenuPanes array.
       
  1772     for(TInt i = 0; i < iMenuPanes.Count(); i++)
       
  1773         {
       
  1774         if(iMenuPanes[i] == aLiwPane)
       
  1775             {
       
  1776             iMenuPanes.Remove(i);
       
  1777             break;                            
       
  1778             }
       
  1779         }
       
  1780     
       
  1781     // Remove the liw menu pane from iMenuLastInitialized array.
       
  1782     for(TInt i = 0; i < iLastInitialized.Count(); i++)
       
  1783         {
       
  1784         if(iLastInitialized[i] == aLiwPane)
       
  1785             {
       
  1786             iLastInitialized.Remove(i);
       
  1787             break;                            
       
  1788             }
       
  1789         }                        
       
  1790     
       
  1791     delete aLiwPane;
       
  1792     aLiwPane = NULL;    
       
  1793     }
       
  1794 
       
  1795 const TInt resourceSlotIds[KMaxMenuResources] =
       
  1796     {
       
  1797     R_LIW_EMPTY_MENU_0,
       
  1798     R_LIW_EMPTY_MENU_1,
       
  1799     R_LIW_EMPTY_MENU_2,
       
  1800     R_LIW_EMPTY_MENU_3,
       
  1801     R_LIW_EMPTY_MENU_4,
       
  1802     R_LIW_EMPTY_MENU_5,
       
  1803     R_LIW_EMPTY_MENU_6,
       
  1804     R_LIW_EMPTY_MENU_7,
       
  1805     R_LIW_EMPTY_MENU_8,
       
  1806     R_LIW_EMPTY_MENU_9,
       
  1807     R_LIW_EMPTY_MENU_10,
       
  1808     R_LIW_EMPTY_MENU_11,
       
  1809     R_LIW_EMPTY_MENU_12,
       
  1810     R_LIW_EMPTY_MENU_13,
       
  1811     R_LIW_EMPTY_MENU_14,
       
  1812     R_LIW_EMPTY_MENU_15
       
  1813     };
       
  1814 
       
  1815 
       
  1816 TInt CLiwServiceHandlerImpl::ResourceIdForNextFreeSlot()
       
  1817     {
       
  1818     if (iNextFreeSlot < KMaxMenuResources)
       
  1819         {
       
  1820         return resourceSlotIds[iNextFreeSlot++];
       
  1821         }
       
  1822 
       
  1823     return -1;
       
  1824     }
       
  1825 
       
  1826 
       
  1827 void CLiwServiceHandlerImpl::SetEmphasis(CCoeControl* /*aMenuControl*/,TBool /*aEmphasis*/)
       
  1828     {
       
  1829     }
       
  1830 
       
  1831 
       
  1832 void CLiwServiceHandlerImpl::ProcessCommandL(TInt /*aCommandId*/) 
       
  1833     {
       
  1834     }
       
  1835 
       
  1836 
       
  1837 // Rewrite this method. It doesn't make sense. Variable j is not used at all.    
       
  1838 TInt CLiwServiceHandlerImpl::MenuCmdId(TInt aMenuCmdId) const
       
  1839     {
       
  1840     TInt ret( KErrNotFound );
       
  1841     
       
  1842     for (TInt i = 0; i < iMenuBindings.Count() && (ret == KErrNotFound); i++)
       
  1843         {
       
  1844         for (TInt j = 0; j < iMenuBindings[i]->NumberOfProviders() && (ret == KErrNotFound); j++)
       
  1845             {
       
  1846             if ((IsInLastInitialized(iMenuBindings[i]->MenuPane())) &&
       
  1847                 (iMenuBindings[i]->MenuPane()->IsCmdInRange(KPlaceholderCmdIdRange, aMenuCmdId)) &&
       
  1848                 (ret == KErrNotFound ))
       
  1849                 {
       
  1850                 ret = iMenuBindings[i]->MenuPane()->MenuCmdId(aMenuCmdId); 
       
  1851                 }   
       
  1852             }
       
  1853         }
       
  1854 
       
  1855     return ret;     
       
  1856     }
       
  1857 
       
  1858 
       
  1859 void Cleanup( TAny* aAny )
       
  1860     {
       
  1861     RImplInfoPtrArray* implArray = 
       
  1862         reinterpret_cast< RImplInfoPtrArray*> ( aAny );
       
  1863     implArray->ResetAndDestroy();
       
  1864     implArray->Close();
       
  1865     }
       
  1866 
       
  1867 
       
  1868 void InterestCleanup( TAny* aAny )
       
  1869     {
       
  1870     RPointerArray<CLiwCriteriaItem>* interestArray = 
       
  1871         reinterpret_cast<RPointerArray<CLiwCriteriaItem>*> ( aAny );
       
  1872 
       
  1873     interestArray->ResetAndDestroy();   
       
  1874     }
       
  1875 
       
  1876 void FilteredCleanup( TAny* aAny )
       
  1877     {
       
  1878     RPointerArray<CLiwCriteriaItem>* filteredArray = 
       
  1879         reinterpret_cast<RPointerArray<CLiwCriteriaItem>*> ( aAny );
       
  1880 
       
  1881     filteredArray->Reset();   
       
  1882     }
       
  1883 
       
  1884 
       
  1885 void IntArrayCleanup(TAny* aAny)
       
  1886     {
       
  1887     RArray<TInt>* intArray = 
       
  1888         reinterpret_cast<RArray<TInt>*> ( aAny );
       
  1889 
       
  1890     intArray->Close();
       
  1891     }
       
  1892 
       
  1893 void Int32ArrayCleanup(TAny* aAny)
       
  1894     {
       
  1895     RArray<TInt32>* intArray = 
       
  1896         reinterpret_cast<RArray<TInt32>*> ( aAny );
       
  1897 
       
  1898     intArray->Close();
       
  1899     }
       
  1900 
       
  1901 void InterfaceCleanup( TAny* aAny )
       
  1902     {
       
  1903     MLiwInterface* interface = reinterpret_cast<MLiwInterface*>(aAny);
       
  1904     interface->Close();
       
  1905     }
       
  1906 
       
  1907 void CLiwServiceHandlerImpl::CopyMenuItemsL(CLiwMenuPane* aSource, CEikMenuPane& aDest, 
       
  1908     TInt aStartIndex, TBool aIsSubmenu)
       
  1909     {
       
  1910     TInt cmdId;
       
  1911     TInt inPos = aStartIndex;
       
  1912 
       
  1913     for (TInt i = 0; i < aSource->MenuPane().NumberOfItemsInPane(); i++)
       
  1914         {
       
  1915         cmdId = aSource->FindCmdId(i);
       
  1916         if (cmdId >= 0)
       
  1917             {
       
  1918             CEikMenuPaneItem::SData itemData = aSource->MenuPane().ItemData(cmdId);
       
  1919             
       
  1920             // The menu item might include alternative texts for a main menu level 
       
  1921             // and for submenu. Use submenu string if it is intended so.       
       
  1922             if(aIsSubmenu)
       
  1923                 {
       
  1924                 const TDesC& extraText = aSource->ExtraText(cmdId);
       
  1925                 if(extraText.Length())
       
  1926                     {
       
  1927                     itemData.iText.Zero();
       
  1928                     itemData.iText.Append(extraText);
       
  1929                     }                 
       
  1930                 }
       
  1931             
       
  1932             aDest.InsertMenuItemL(itemData, inPos++);
       
  1933             }   
       
  1934         }   
       
  1935     }
       
  1936 
       
  1937 
       
  1938 
       
  1939 TInt CLiwServiceHandlerImpl::SlotItemCmd(CEikMenuPane& aPane)
       
  1940     {
       
  1941     TInt index;
       
  1942 
       
  1943     for (TInt i = 0; i < KMaxMenuResources; i++)
       
  1944         {
       
  1945         if (aPane.MenuItemExists(ELiwMenuSlotBase + i, index))
       
  1946             {
       
  1947             return ELiwMenuSlotBase + i;
       
  1948             }
       
  1949         }
       
  1950 
       
  1951     return -1;
       
  1952     }
       
  1953 
       
  1954 
       
  1955 
       
  1956 CLiwMenuPane* CLiwServiceHandlerImpl::MenuPaneForSlotCmd(TInt aCmdId)
       
  1957     {
       
  1958     TInt index = aCmdId - ELiwMenuSlotBase; 
       
  1959 
       
  1960     if (index < KMaxMenuResources)
       
  1961         {
       
  1962         TInt resId = resourceSlotIds[index];
       
  1963         for (TInt i = 0; i < iMenuPanes.Count(); i++)
       
  1964             {
       
  1965             if (iMenuPanes[i]->ResourceSlotId() == resId)
       
  1966                 {
       
  1967                 return iMenuPanes[i];
       
  1968                 }
       
  1969             }
       
  1970         }
       
  1971 
       
  1972     return NULL;
       
  1973     }
       
  1974 
       
  1975 
       
  1976 
       
  1977 CLiwServiceHandlerImpl::TLiwPlaceholderType CLiwServiceHandlerImpl::PlaceholderType(
       
  1978     CEikMenuPane& aPane, TInt aCmd, TBool& aTitleLocked)
       
  1979     {
       
  1980     CEikMenuPaneItem::SData& itemData = aPane.ItemData(aCmd);
       
  1981 
       
  1982     aTitleLocked = EFalse;
       
  1983 
       
  1984     if ((itemData.iCascadeId & LIW_CASCADE_ID) == LIW_CASCADE_ID)
       
  1985         {
       
  1986         if (itemData.iCascadeId & LIW_LOCK_SUBMENU_TITLE)
       
  1987             {
       
  1988             aTitleLocked = ETrue;
       
  1989             }
       
  1990         return ELiwPlaceholderCascade;
       
  1991         }
       
  1992     else if ((itemData.iCascadeId & LIW_INTELLIGENT_CASCADE_ID) == LIW_INTELLIGENT_CASCADE_ID)
       
  1993         {
       
  1994         if (itemData.iCascadeId & LIW_LOCK_SUBMENU_TITLE)
       
  1995             {
       
  1996             aTitleLocked = ETrue;
       
  1997             }
       
  1998         return ELiwPlaceholderIntelligentCascade;
       
  1999         }
       
  2000 
       
  2001     return ELiwPlaceholderNormal;
       
  2002     }
       
  2003 
       
  2004 
       
  2005 
       
  2006 void CLiwServiceHandlerImpl::ConvertPlaceholderL(CEikMenuPane& aPane, TInt aCmd, 
       
  2007     CLiwMenuPane& aLiwPane, const TDesC& aTitle)
       
  2008     {
       
  2009     CEikMenuPaneItem::SData itemData = aPane.ItemData(aCmd);
       
  2010     TInt index;
       
  2011 
       
  2012     // Remenber index.
       
  2013     aPane.MenuItemExists(aCmd, index);
       
  2014 
       
  2015     // Remove placeholder item.
       
  2016     aPane.DeleteMenuItem(aCmd);
       
  2017 
       
  2018     // Replace liw cascade id with actual menu resource id.
       
  2019     itemData.iCascadeId = aLiwPane.iResourceSlotId;
       
  2020 
       
  2021     if (aTitle.Length())
       
  2022         {
       
  2023         itemData.iText.Copy(aTitle);
       
  2024         }
       
  2025 
       
  2026     // Set unused dynamic cmd id.   
       
  2027     itemData.iCommandId = iSubmenuCmd++;
       
  2028 
       
  2029     // Insert cascade item.
       
  2030     aPane.InsertMenuItemL(itemData, index);
       
  2031     }
       
  2032 
       
  2033 
       
  2034 
       
  2035 void CLiwServiceHandlerImpl::UnCascadeL(CEikMenuPane& aPane, TInt aCmd, CLiwMenuPane& aLiwPane)
       
  2036     {
       
  2037     CEikMenuPaneItem::SData itemData = aLiwPane.MenuPane().ItemData(aLiwPane.FindCmdId(0));
       
  2038     TInt index;
       
  2039 
       
  2040     // Remenber index.
       
  2041     aPane.MenuItemExists(aCmd, index);
       
  2042 
       
  2043     // Remove placeholder item.
       
  2044     aPane.DeleteMenuItem(aCmd);
       
  2045 
       
  2046     // Uncascade 
       
  2047     itemData.iCascadeId = 0;
       
  2048 
       
  2049     // Insert cascade item.
       
  2050     aPane.InsertMenuItemL(itemData, index);     
       
  2051     }
       
  2052 
       
  2053 
       
  2054 
       
  2055 void CLiwServiceHandlerImpl::SkipMenuFields(TResourceReader& aReader)
       
  2056     {
       
  2057     aReader.ReadInt32(); // Skip cascade id
       
  2058     aReader.ReadInt32(); // Skip flags
       
  2059     aReader.ReadTPtrC(); // Skip text
       
  2060     aReader.ReadTPtrC(); // Skip extra text
       
  2061     aReader.ReadTPtrC(); // Skip bmpfile.
       
  2062     aReader.ReadInt16(); // Skip bmpid.
       
  2063     aReader.ReadInt16(); // Skip bmpmask. 
       
  2064     aReader.ReadInt32(); // Skip extension.   
       
  2065     }
       
  2066 
       
  2067 
       
  2068 TBool CLiwServiceHandlerImpl::IsLiwMenu(TInt aMenuResourceId)
       
  2069     {
       
  2070     TInt index;
       
  2071 
       
  2072     // First check if this is liw submenu id
       
  2073     for (index = 0; index < KMaxMenuResources; index++)
       
  2074         {
       
  2075         if (aMenuResourceId == resourceSlotIds[index])
       
  2076             {
       
  2077             return ETrue;
       
  2078             }
       
  2079         }
       
  2080 
       
  2081     // Then check if this menu is among attached menus.
       
  2082     for (index = 0; index < iMenuBindings.Count(); index++)
       
  2083         {
       
  2084         if (iMenuBindings[index]->MenuId() == aMenuResourceId)
       
  2085             {
       
  2086             return ETrue;
       
  2087             }
       
  2088         }
       
  2089 
       
  2090     return EFalse;
       
  2091     }
       
  2092 
       
  2093 
       
  2094 
       
  2095 TBool CLiwServiceHandlerImpl::HandleSubmenuL(CEikMenuPane& aPane)
       
  2096     {
       
  2097     TInt slotcmd = SlotItemCmd(aPane);
       
  2098     if (slotcmd >= 0)
       
  2099         {
       
  2100         // aPane is liw submenu. At this point it is empty and we must
       
  2101         // copy provider menu items to it.
       
  2102         CLiwMenuPane* liwPane = MenuPaneForSlotCmd(slotcmd);
       
  2103         if (liwPane)
       
  2104             {
       
  2105             CopyMenuItemsL(liwPane, aPane, 0, ETrue);
       
  2106             aPane.DeleteMenuItem(slotcmd);
       
  2107             iSubmenu = liwPane;     
       
  2108             return ETrue;
       
  2109             }
       
  2110         }
       
  2111 
       
  2112     return EFalse;
       
  2113     }
       
  2114 
       
  2115 
       
  2116 
       
  2117 TBool CLiwServiceHandlerImpl::GetSubmenuTitle(CEikMenuPane& aPane, TDes& aResult)
       
  2118     {
       
  2119     TInt index;
       
  2120     
       
  2121     aResult.Zero();
       
  2122     while (aPane.MenuItemExists(LIW_SUBMENU_TITLE, index))
       
  2123         {
       
  2124         CEikMenuPaneItem::SData& itemData = aPane.ItemData(LIW_SUBMENU_TITLE);
       
  2125         if (aResult.Length() == 0)
       
  2126             {
       
  2127             aResult.Copy(itemData.iText);
       
  2128             }
       
  2129         aPane.DeleteMenuItem(LIW_SUBMENU_TITLE);
       
  2130         return ETrue;
       
  2131         }
       
  2132 
       
  2133     return EFalse;
       
  2134     }
       
  2135 
       
  2136 
       
  2137 
       
  2138 CLiwCriteriaItem* CLiwServiceHandlerImpl::ConvertCriteriaItemPointerL(CLiwCriteriaItem* aCandidate)
       
  2139     {
       
  2140     for (TInt index = 0; index < iInterestList.Count(); index++)
       
  2141         {
       
  2142         if ((*iInterestList[index]) == (*aCandidate))
       
  2143             {
       
  2144             // Already in list, aCandidate is not needed.
       
  2145             delete aCandidate;
       
  2146             return iInterestList[index];
       
  2147             }
       
  2148         }
       
  2149 
       
  2150     CleanupStack::PushL(aCandidate);
       
  2151     User::LeaveIfError(iInterestList.Append(aCandidate));
       
  2152     CleanupStack::Pop(aCandidate); // aCandidate
       
  2153 
       
  2154     return aCandidate;
       
  2155     }
       
  2156 
       
  2157 
       
  2158 
       
  2159 void CLiwServiceHandlerImpl::FilterInterestListL(RPointerArray<CLiwCriteriaItem>& aOrginal,
       
  2160     RPointerArray<CLiwCriteriaItem>& aFiltered)
       
  2161     {
       
  2162     CLiwCriteriaItem* item;
       
  2163 
       
  2164     while (aOrginal.Count() > 0)
       
  2165         {
       
  2166         item = aOrginal[0];
       
  2167         aOrginal.Remove(0);
       
  2168         item = ConvertCriteriaItemPointerL(item);
       
  2169         User::LeaveIfError(aFiltered.Append(item));
       
  2170         }
       
  2171     aOrginal.Reset();
       
  2172     }
       
  2173 
       
  2174 
       
  2175 
       
  2176 void CLiwServiceHandlerImpl::RemoveProvider(TInt aImplUid)
       
  2177     {
       
  2178     TInt index;
       
  2179 
       
  2180     // First go through bindings and remove all the 
       
  2181     // references to given provider.
       
  2182     for (index = 0; index < iBaseBindings.Count(); index++)
       
  2183         {
       
  2184         iBaseBindings[index]->RemoveProvider(aImplUid);
       
  2185         }
       
  2186 
       
  2187     for (index = 0; index < iMenuBindings.Count(); index++)
       
  2188         {
       
  2189         iMenuBindings[index]->RemoveProvider(aImplUid);
       
  2190         }
       
  2191     
       
  2192     // Then remove provider from the owner list and delete it.
       
  2193     for (index = 0; index < iProviders.Count(); index++)
       
  2194         {
       
  2195         if (iProviders[index]->ImplementationUid().iUid == aImplUid)
       
  2196             {
       
  2197             delete iProviders[index];
       
  2198             iProviders.Remove(index);
       
  2199             index--;
       
  2200             }
       
  2201         }
       
  2202     }
       
  2203 
       
  2204 
       
  2205 void CLiwServiceHandlerImpl::AddProviderL(TUid aImplUid, CLiwCriteriaItem* aItem)
       
  2206     {
       
  2207     TInt index;
       
  2208     CLiwServiceIfBase* iface = iEcomMonitor->CreateImplementationL(aImplUid);
       
  2209     
       
  2210     if (iface)
       
  2211         {
       
  2212         CleanupStack::PushL(iface);
       
  2213         iface->AddCriteria(aItem);
       
  2214         User::LeaveIfError(iProviders.Append( iface ));
       
  2215         CleanupStack::Pop(iface);
       
  2216 
       
  2217         for (index = 0; index < iBaseBindings.Count(); index++)
       
  2218             {
       
  2219             if (iBaseBindings[index]->HasCriteriaItem(*aItem) != KErrNotFound)
       
  2220                 {
       
  2221                 iBaseBindings[index]->AddProviderL(iface, aImplUid == aItem->DefaultProvider());
       
  2222                 iface->InitialiseL(*this, iBaseBindings[index]->Interest());
       
  2223                 }               
       
  2224             }
       
  2225 
       
  2226         for (index = 0; index < iMenuBindings.Count(); index++)
       
  2227             {
       
  2228             if (iMenuBindings[index]->HasCriteriaItem(*aItem) != KErrNotFound)
       
  2229                 {
       
  2230                 iMenuBindings[index]->AddProviderL(iface, aImplUid == aItem->DefaultProvider());
       
  2231                 iface->InitialiseL(*this, iMenuBindings[index]->Interest());
       
  2232                 }               
       
  2233             }
       
  2234         }
       
  2235     }
       
  2236 
       
  2237 
       
  2238 
       
  2239 TInt CLiwServiceHandlerImpl::SynchronizeCallBack(TAny* aImpl)
       
  2240     {
       
  2241     CLiwServiceHandlerImpl* impl = reinterpret_cast<CLiwServiceHandlerImpl*>(aImpl);
       
  2242     TRAPD(err, impl->SynchronizeDbL());
       
  2243     return err;
       
  2244     }
       
  2245 
       
  2246 
       
  2247 
       
  2248 void CLiwServiceHandlerImpl::SynchronizeDbL()
       
  2249     {
       
  2250     TInt index;
       
  2251     RArray<TInt> providers;
       
  2252     RImplInfoPtrArray infoArray;
       
  2253 
       
  2254     CleanupStack::PushL( TCleanupItem( IntArrayCleanup, &providers ) );
       
  2255     CleanupStack::PushL( TCleanupItem( Cleanup, &infoArray ) );
       
  2256 
       
  2257     for (index = 0; index < iInterestList.Count(); index++)
       
  2258         {
       
  2259         if (iInterestList[index]->RomOnly())  // Rom-only criterias can be skipped.
       
  2260             {
       
  2261             continue;
       
  2262             }
       
  2263 
       
  2264         providers.Reset();
       
  2265         infoArray.ResetAndDestroy();
       
  2266         ListProvidersForCriteriaL(providers, *(iInterestList[index]));
       
  2267         iEcomMonitor->ListImplemetationsL(infoArray, iInterestList[index]);
       
  2268         HandleRemovedProviders(providers, infoArray);          
       
  2269         HandleNewProvidersL(providers, infoArray, iInterestList[index]);        
       
  2270         }
       
  2271 
       
  2272     CleanupStack::PopAndDestroy(&infoArray); // providers, infoArray
       
  2273     CleanupStack::PopAndDestroy(&providers);
       
  2274     }
       
  2275 
       
  2276 
       
  2277 void CLiwServiceHandlerImpl::HandleRemovedProviders(RArray<TInt>& aInMemory, 
       
  2278     RImplInfoPtrArray& aInSystem)
       
  2279     {
       
  2280     TInt index, index2;
       
  2281 
       
  2282     for (index = 0; index < aInMemory.Count(); index++)
       
  2283         {
       
  2284         for (index2 = 0; index2 < aInSystem.Count(); index2++)
       
  2285             {
       
  2286             if (aInSystem[index2]->ImplementationUid().iUid == aInMemory[index])
       
  2287                 {
       
  2288                 break;
       
  2289                 }
       
  2290             }
       
  2291         if (index2 >= aInSystem.Count())  // Was removed from system.
       
  2292             {
       
  2293             RemoveProvider(aInMemory[index]);
       
  2294             }
       
  2295         }
       
  2296     }
       
  2297 
       
  2298 
       
  2299 void CLiwServiceHandlerImpl::HandleNewProvidersL(RArray<TInt>& aInMemory, 
       
  2300     RImplInfoPtrArray& aInSystem, CLiwCriteriaItem* aItem)
       
  2301     {
       
  2302     TInt index;
       
  2303 
       
  2304     for (index = 0; index < aInSystem.Count(); index++)
       
  2305         {
       
  2306         if (aInMemory.Find(aInSystem[index]->ImplementationUid().iUid) == KErrNotFound)
       
  2307             {
       
  2308             AddProviderL(aInSystem[index]->ImplementationUid(), aItem);
       
  2309             }       
       
  2310         }
       
  2311     }
       
  2312     
       
  2313 void CLiwServiceHandlerImpl::MenuLaunched()
       
  2314     {  
       
  2315     ClearMenuPaneArray();
       
  2316     iNextFreeSlot = 0;
       
  2317     iLastInitialized.Reset();
       
  2318 
       
  2319     // Reset the iMenuPane pointers from iMenuBindings.
       
  2320     for(TInt index = 0; index < iMenuBindings.Count(); index++)
       
  2321         {
       
  2322         iMenuBindings[index]->SetMenuPane(NULL);
       
  2323         }
       
  2324     }
       
  2325 
       
  2326 /* Utility function to get the symbian TCapability enum value
       
  2327  * from the string defined in the providers xml file
       
  2328  *
       
  2329  * @param aCapName name of the capabiility to be converted to \c TCapability enum
       
  2330  *
       
  2331  */
       
  2332 
       
  2333 TCapability CLiwServiceHandlerImpl::GetServiceCapability(const TDesC& aCapName)
       
  2334 {
       
  2335 	TCapability cap(ECapability_None);
       
  2336 
       
  2337 	if(0==aCapName.Compare(KCapabilityCommDD))
       
  2338 	{
       
  2339 		cap=ECapabilityCommDD;
       
  2340 	}
       
  2341 	else if(0==aCapName.Compare(KCapabilityPowerMgmt))
       
  2342 	{
       
  2343 		cap=ECapabilityPowerMgmt;
       
  2344 	}
       
  2345 	else if(0==aCapName.Compare(KCapabilityMultimediaDD))
       
  2346 	{
       
  2347 		cap=ECapabilityMultimediaDD;
       
  2348 	}
       
  2349 	else if(0==aCapName.Compare(KCapabilityReadDeviceData))
       
  2350 	{
       
  2351 		cap=ECapabilityReadDeviceData;
       
  2352 	}
       
  2353 	else if(0==aCapName.Compare(KCapabilityWriteDeviceData))
       
  2354 	{
       
  2355 		cap=ECapabilityWriteDeviceData;
       
  2356 	}
       
  2357 	else if(0==aCapName.Compare(KCapabilityDRM))
       
  2358 	{
       
  2359 		cap=ECapabilityDRM;
       
  2360 	}
       
  2361 	else if(0==aCapName.Compare(KCapabilityTrustedUI))
       
  2362 	{
       
  2363 		cap=ECapabilityTrustedUI;
       
  2364 	}
       
  2365 	else if(0==aCapName.Compare(KCapabilityProtServ))
       
  2366 	{
       
  2367 		cap=ECapabilityProtServ;
       
  2368 	}
       
  2369 	else if(0==aCapName.Compare(KCapabilityDiskAdmin))
       
  2370 	{
       
  2371 		cap=ECapabilityDiskAdmin;
       
  2372 	}
       
  2373 	else if(0==aCapName.Compare(KCapabilityNetworkControl))
       
  2374 	{
       
  2375 		cap=ECapabilityNetworkControl;
       
  2376 	}
       
  2377 	else if(0==aCapName.Compare(KCapabilityAllFiles))
       
  2378 	{
       
  2379 		cap=ECapabilityAllFiles;
       
  2380 	}
       
  2381 	else if(0==aCapName.Compare(KCapabilitySwEvent))
       
  2382 	{
       
  2383 		cap=ECapabilitySwEvent;
       
  2384 	}
       
  2385 	else if(0==aCapName.Compare(KCapabilityNetworkServices))
       
  2386 	{
       
  2387 		cap=ECapabilityNetworkServices;
       
  2388 	}
       
  2389 	else if(0==aCapName.Compare(KCapabilityLocalServices))
       
  2390 	{
       
  2391 		cap=ECapabilityLocalServices;
       
  2392 	}
       
  2393 	else if(0==aCapName.Compare(KCapabilityReadUserData))
       
  2394 	{
       
  2395 		cap=ECapabilityReadUserData;
       
  2396 	}
       
  2397 	else if(0==aCapName.Compare(KCapabilityWriteUserData))
       
  2398 	{
       
  2399 		cap=ECapabilityWriteUserData;
       
  2400 	}
       
  2401 	else if(0==aCapName.Compare(KCapabilityLocation))
       
  2402 	{
       
  2403 		cap=ECapabilityLocation;
       
  2404 	}
       
  2405 	else if(0==aCapName.Compare(KCapabilitySurroundingsDD))
       
  2406 	{
       
  2407 		cap=ECapabilitySurroundingsDD;
       
  2408 	}
       
  2409 	else if(0==aCapName.Compare(KCapabilityUserEnvironment))
       
  2410 	{
       
  2411 		cap=ECapabilityUserEnvironment;
       
  2412 	}
       
  2413 
       
  2414 	return cap;
       
  2415 }
       
  2416 
       
  2417 
       
  2418 /**
       
  2419 * Returns the capability set defined in the service provider
       
  2420 * metadata information. The capability set is a pre-requisite
       
  2421 * for the service consumer to load the service provider module.
       
  2422 *
       
  2423 * The capability metadata information are defined as XML character
       
  2424 * data inside the element <capability/>. The capability information
       
  2425 * are type of metadata information. Hence, the capability element tags
       
  2426 * should appear as child element of <metadata> element.
       
  2427 *
       
  2428 * @param aCapability Capability set that the consumer should posess while
       
  2429 *		 loading the service provider
       
  2430 *
       
  2431 * @example
       
  2432 *
       
  2433 * @code
       
  2434 * <!-- consumer should posess the following capability set -->
       
  2435 * <metadata>
       
  2436 *	<capability>CapabilityReadUserData</capability>
       
  2437 *	<capability>CapabilityWriteUserData</capability>
       
  2438 *	<capability>CapabilityDRM</capability>
       
  2439 * </metadata>
       
  2440 * @endcode
       
  2441 *
       
  2442 */
       
  2443 
       
  2444 void CLiwServiceHandlerImpl::GetCapabilitiesL(RArray<TCapability>& secMgrCapList,CLiwGenericParamList* pMetaData)
       
  2445 {	
       
  2446 	_LIT8(KCapability,"cap");
       
  2447 
       
  2448 	TInt pos = 0;
       
  2449 	const TLiwGenericParam* pCapData = pMetaData->FindFirst(pos,KCapability);
       
  2450 
       
  2451 	if(pCapData)
       
  2452 	{
       
  2453 		const CLiwList* pCapList = pCapData->Value().AsList();
       
  2454 		if(pCapList)
       
  2455 		{
       
  2456 			for(TInt idx(0);idx!=pCapList->Count();++idx)
       
  2457 			{
       
  2458 				TLiwVariant capVar;
       
  2459 				capVar.PushL();
       
  2460 				pCapList->AtL(idx, capVar);
       
  2461 				TPtrC capStr = capVar.AsDes();
       
  2462 				
       
  2463 				TCapability cap = this->GetServiceCapability(capStr);
       
  2464 				if( (cap>=ECapabilityTCB)  && (cap < ECapability_Limit))
       
  2465 					secMgrCapList.AppendL(cap);
       
  2466 				CleanupStack::Pop(&capVar);
       
  2467 				capVar.Reset();
       
  2468 			}
       
  2469 		}
       
  2470 		
       
  2471 	}
       
  2472 }
       
  2473 
       
  2474 void CLiwServiceHandlerImpl::GetProviderResourceFile(TDes& aFilePath,CLiwGenericParamList* pMetaData)
       
  2475 {	
       
  2476 	_LIT8(KResourceFile,"res");
       
  2477 
       
  2478 	TInt pos = 0;
       
  2479 	const TLiwGenericParam* pCapData = pMetaData->FindFirst(pos,KResourceFile);
       
  2480 
       
  2481 	if(pCapData)
       
  2482 	{
       
  2483 		const CLiwList* pCapList = pCapData->Value().AsList();
       
  2484 		if(pCapList)
       
  2485 		{
       
  2486 			for(TInt idx(0);idx!=pCapList->Count();++idx)
       
  2487 			{
       
  2488 				TLiwVariant capVar;
       
  2489 				capVar.PushL();
       
  2490 				pCapList->AtL(idx, capVar);
       
  2491 				aFilePath = capVar.AsDes();
       
  2492 				CleanupStack::Pop(&capVar);
       
  2493 				capVar.Reset();
       
  2494 			}
       
  2495 		}
       
  2496 		
       
  2497 	}
       
  2498 }
       
  2499 
       
  2500 void CLiwServiceHandlerImpl::ComputeIntfVersion(CLiwServiceData* pProvMetaData,TReal& aIntfVersion)
       
  2501 {
       
  2502 	CLiwGenericParamList* pMetaDataList = pProvMetaData->GetMetaData();
       
  2503 	
       
  2504 	if(pMetaDataList)
       
  2505 	{	
       
  2506 		TInt verPos(KErrNone);
       
  2507 		_LIT8(KVer,"ver");
       
  2508 		const TLiwGenericParam* pVerParam = pMetaDataList->FindFirst(verPos,KVer);
       
  2509 		if(pVerParam)
       
  2510 		{
       
  2511 			const CLiwList* pVersionList = pVerParam->Value().AsList(); 
       
  2512 			if(pVersionList)
       
  2513 			{
       
  2514 				if(pVersionList->Count())
       
  2515 				{
       
  2516 					TLiwVariant verVar;
       
  2517 					verVar.PushL();
       
  2518 					pVersionList->AtL(0,verVar);//pick up the value in 0th index..
       
  2519 					aIntfVersion = verVar.AsTReal();
       
  2520 					CleanupStack::Pop(&verVar);
       
  2521 					verVar.Reset();
       
  2522 				}					
       
  2523 			}			
       
  2524 		}	
       
  2525 	}	
       
  2526 }
       
  2527 
       
  2528 
       
  2529 TInt CLiwServiceHandlerImpl::ResolveProvidersL(CLiwBinding* aBinding, 
       
  2530 					       CLiwCriteriaItem* aItem,
       
  2531 					       CRTSecMgrScriptSession* aScriptSession)
       
  2532     {
       
  2533     TInt result = 0;
       
  2534     TInt status = KLiwUnknown;
       
  2535 
       
  2536     // First resolve for providers already in memory.
       
  2537     TInt index;
       
  2538     for (index = 0; index < iProviders.Count(); index++)
       
  2539         {
       
  2540         if (iProviders[index]->Match(aItem))
       
  2541             {
       
  2542             aBinding->AddProviderL((CLiwServiceIfBase*)iProviders[index], 
       
  2543                 iProviders[index]->ImplementationUid() == aItem->DefaultProvider());          
       
  2544             result++;
       
  2545             }     
       
  2546         }
       
  2547 
       
  2548 
       
  2549     // If cached providers were found, then it means that all the matching
       
  2550     // providers must be already in memory. No need to query from ECom framework.
       
  2551     if (!result)
       
  2552         {
       
  2553         RImplInfoPtrArray infoArray;
       
  2554         RArray<TInt32> infoArrayPlugin;
       
  2555 
       
  2556         CleanupStack::PushL( TCleanupItem( Cleanup, &infoArray ) );
       
  2557         CleanupStack::PushL( TCleanupItem( Int32ArrayCleanup, &infoArrayPlugin ) );
       
  2558         
       
  2559         iEcomMonitor->ListImplemetationsL(infoArray, aItem);
       
  2560         
       
  2561         FilterInfoArray(infoArray, infoArrayPlugin, aItem);
       
  2562 
       
  2563 		CLiwServiceData* pServiceData = NULL;
       
  2564 		
       
  2565 		CLiwServiceData* pPrevSData = NULL;
       
  2566 		
       
  2567 		CImplementationInformation* pChosenImpl = NULL;
       
  2568 		
       
  2569 		TReal currentMax(KDefVersion); 
       
  2570 
       
  2571         for (index = 0; index < infoArray.Count(); index++)
       
  2572             {
       
  2573             TBool stackPop = EFalse;
       
  2574             if ((aItem->Options() & LIW_OPTIONS_ROM_ONLY) && (infoArray[index]->RomBased() == EFalse))
       
  2575                 {
       
  2576                 continue;
       
  2577                 }
       
  2578     
       
  2579     		//Check whether consumer has capability
       
  2580     		//mandated by provider
       
  2581     		CImplementationInformation* pImplInfo = infoArray[index];
       
  2582     		
       
  2583     		TBuf8<KMaxLength> opaq;
       
  2584     		
       
  2585     		ParseMetaData(pImplInfo->OpaqueData(),opaq);
       
  2586     		
       
  2587     		CLiwXmlHandler* pXmlHandler = CLiwXmlHandler::NewLC();
       
  2588     		
       
  2589 			pServiceData = CLiwServiceData::NewLC();
       
  2590     		
       
  2591     		TInt loadStatus= CLiwXmlHandler::ESrvDataLoadFailed;
       
  2592     		
       
  2593     		//Inline metadata defined
       
  2594     		if(opaq.Length()>0)
       
  2595     		{
       
  2596     			loadStatus=pXmlHandler->LoadServiceData(opaq,pServiceData);
       
  2597     		}
       
  2598     		else
       
  2599     		{
       
  2600     			//Obtain the capabilities from the metadata
       
  2601 	    		TUid implUid = pImplInfo->ImplementationUid();
       
  2602 	    		TUidName srvProvUid = implUid.Name();
       
  2603 	    
       
  2604 	    		
       
  2605 	    		TPtrC16 ptrSrv = srvProvUid.Right(srvProvUid.Length()-1);
       
  2606 	    		TPtrC16 srvFile = ptrSrv.Left(ptrSrv.Length()-1);		
       
  2607 	    		TDriveUnit driveUnit = pImplInfo->Drive();
       
  2608 	    		TFileName fileName = driveUnit.Name();
       
  2609 	    		fileName.Append(KDC_RESOURCE_FILES_DIR);
       
  2610 	    		fileName.Append(srvFile);
       
  2611 	    		fileName.Append(KPerExtension);
       
  2612 	    		loadStatus=pXmlHandler->LoadServiceData(fileName,pServiceData);
       
  2613     		}
       
  2614     		
       
  2615     		/*
       
  2616     		 *  - Get version range specified by the consumer
       
  2617     		 *  - Iterate over the list of intf impl
       
  2618     		 *
       
  2619     		 * //LOOP:
       
  2620     		 *  - For each implementation item,
       
  2621     		 *
       
  2622     		 *  	- Check if intf impl has version tag from its metadata
       
  2623     		 *		- Pick up interface impl's version tag
       
  2624     		 *		- If intf impl has NO specifed version tag
       
  2625     		 *			- set this intf impl version as DEFAULT VERSION (//pref 1.0)..
       
  2626     		 *
       
  2627     		 *   //CHOOSE LATEST VERSION:
       
  2628     		 *		- If consumer has specifed version range
       
  2629     		 *			- CALL COMPARE routine (//To check if this is the latest version so far)
       
  2630     		 *				- Mark this as the chosen implementation
       
  2631     		 *			- Else (//This is NOT the latest)
       
  2632     		 *				- Continue;
       
  2633     		 *
       
  2634     		 *		- Else (//If consumer did not specify version range)
       
  2635     		 *			- CALL COMPARE routine (//To check if this is the latest version so far)
       
  2636     		 *				- Mark this as the chosen implementation
       
  2637     		 *			- Else (//This is NOT the latest)
       
  2638     		 *				- Continue;
       
  2639     		 *  	
       
  2640     		 *  //COMPARE (currentMax,implVersion,minVer,maxVer): //default minVer=1.0
       
  2641     		 *		- if(implVersion>currentMax)
       
  2642     		 *			- if(implVersion>=minVer && implVersion<=maxVer)
       
  2643     		 *				- currentMax = implVersion;
       
  2644     		 *				- return; //mark pServiceData to point to the current impl's service data
       
  2645     		 *			- else
       
  2646     		 *				- return; //leave pServiceData as it is
       
  2647     		 *		- else
       
  2648     		 *			- return; //leave pServiceData as it is
       
  2649     		 *
       
  2650     		 */
       
  2651     		 
       
  2652     		if(CLiwXmlHandler::ESrvDataLoadSuccess==loadStatus) //metadata is parsed successfully
       
  2653     		{
       
  2654     			TReal implVersion(KDefVersion);
       
  2655     			this->ComputeIntfVersion(pServiceData,implVersion); //fetch impl version..
       
  2656     			
       
  2657     			TReal minVer(KDefVersion);
       
  2658     			TReal maxVer(KUnspVersion);
       
  2659     			
       
  2660     			TBool verChk = this->GetVersionRange(aItem,minVer,maxVer);
       
  2661     			
       
  2662     			if(verChk) //Get version queried by consumer
       
  2663     			{
       
  2664     				if(minVer == KUnspVersion)
       
  2665     					minVer = KDefVersion;
       
  2666     				
       
  2667     				//perform comparison...
       
  2668     				if(implVersion>=currentMax)
       
  2669     				{
       
  2670     					if(maxVer!=KUnspVersion)
       
  2671     					{
       
  2672 	    					if((implVersion>=minVer) && (implVersion<=maxVer))
       
  2673 	    					{
       
  2674 	    						currentMax = implVersion;
       
  2675 	    						pChosenImpl = infoArray[index];
       
  2676 	    						//current impl is the best choice..this is THE CHOSEN ONE..
       
  2677 	    						if(pPrevSData)
       
  2678 	    						{
       
  2679 	    							pPrevSData->CleanUpMetaData();
       
  2680 	    							delete pPrevSData;
       
  2681 	    							
       
  2682 	    						}
       
  2683 	    						
       
  2684 	    						pPrevSData = pServiceData;
       
  2685 	    						
       
  2686 	    					}
       
  2687 	    					else
       
  2688 	    					{
       
  2689 	    						//current impl is NOT THE RIGHT CHOICE.. since not within the range
       
  2690 		    					if(pServiceData)
       
  2691 		    					{
       
  2692 		    						if(!stackPop)
       
  2693 						    		{
       
  2694 							    		stackPop = ETrue;
       
  2695 										CleanupStack::Pop(pServiceData);	
       
  2696 						    		}
       
  2697 						    		pServiceData->CleanUpMetaData();
       
  2698 		    						delete pServiceData;
       
  2699 		    						pServiceData = NULL;
       
  2700 		    					}
       
  2701 		    					status = KLiwVersionOutOfRange;
       
  2702 	    					}
       
  2703     					}
       
  2704     					else
       
  2705     					{
       
  2706     						//means maxVer == KUnspVersion
       
  2707     						if(implVersion>=minVer)
       
  2708 	    					{
       
  2709 	    						currentMax = implVersion;
       
  2710 	    						pChosenImpl = infoArray[index];
       
  2711 	    						
       
  2712 	    						//current impl is the best choice..this is THE CHOSEN ONE..
       
  2713 	    						if(pPrevSData)
       
  2714 	    						{
       
  2715 	    							pPrevSData->CleanUpMetaData();
       
  2716 	    							delete pPrevSData;
       
  2717 	    						}
       
  2718 	    						
       
  2719 	    						pPrevSData = pServiceData;
       
  2720 	    				 	}
       
  2721 	    					else
       
  2722 	    					{
       
  2723 	    						//current impl is NOT THE RIGHT CHOICE..
       
  2724 		    					if(pServiceData)
       
  2725 		    					{
       
  2726 		    						if(!stackPop)
       
  2727 						    		{
       
  2728 							    		stackPop = ETrue;
       
  2729 										CleanupStack::Pop(pServiceData);	
       
  2730 						    		}
       
  2731 		    						pServiceData->CleanUpMetaData();
       
  2732 		    						delete pServiceData;
       
  2733 		    						pServiceData = NULL;
       
  2734 		    					}
       
  2735 		    					
       
  2736 		    					status = KLiwVersionOutOfRange;
       
  2737 	    					 }
       
  2738     					}
       
  2739     				}
       
  2740     				else
       
  2741     				{
       
  2742     					//current impl is NOT THE RIGHT CHOICE..since implVer > maxVer
       
  2743     					if(pServiceData)
       
  2744     					{
       
  2745     						if(!stackPop)
       
  2746 				    		{
       
  2747 					    		stackPop = ETrue;
       
  2748 								CleanupStack::Pop(pServiceData);	
       
  2749 				    		}
       
  2750 		    				pServiceData->CleanUpMetaData();
       
  2751     						delete pServiceData;
       
  2752     						pServiceData = NULL;
       
  2753     					}
       
  2754     					
       
  2755     					status = KLiwVersionOutOfRange;
       
  2756     				}    				
       
  2757     			}
       
  2758     			else
       
  2759     			{
       
  2760     				//GetVersionRange Fails.. 
       
  2761     				//abort service resolution process..
       
  2762     				if(pServiceData)
       
  2763 					{
       
  2764 						if(!stackPop)
       
  2765 			    		{
       
  2766 				    		stackPop = ETrue;
       
  2767 							CleanupStack::Pop(pServiceData);	
       
  2768 			    		}
       
  2769 			    		pServiceData->CleanUpMetaData();
       
  2770 						delete pServiceData;
       
  2771 						pServiceData = NULL;
       
  2772 					} 
       
  2773 					
       
  2774     				status = KLiwInvalidVersionSpecification;
       
  2775     			}
       
  2776     			
       
  2777 	    		//other cases like parse error, capability not
       
  2778 	    		//specified in meta data are handled
       
  2779 				
       
  2780     			if(currentMax == implVersion)
       
  2781 		    	{
       
  2782 			    	if(pPrevSData && (pPrevSData!=pServiceData)) //just in case...
       
  2783 			    	{
       
  2784 			    		pPrevSData->CleanUpMetaData();
       
  2785 						delete pPrevSData;
       
  2786 						pPrevSData = NULL;
       
  2787 			    	}	
       
  2788 		    	}
       
  2789 		    	else
       
  2790 		    	{
       
  2791 		    		if(!stackPop)
       
  2792 		    		{
       
  2793 			    		stackPop = ETrue;
       
  2794 						CleanupStack::Pop(pServiceData);	
       
  2795 		    		}
       
  2796 					pServiceData = pPrevSData;
       
  2797 		    	}	
       
  2798     		}
       
  2799     		else
       
  2800     		{
       
  2801     			//Metadata specification not found.. Hence Load Fails
       
  2802     			if(CLiwXmlHandler::ESrvDataFileNotFnd==loadStatus)
       
  2803     			{	
       
  2804 					pChosenImpl = infoArray[index];    				
       
  2805     			}
       
  2806     			else  //Some error like parse error, capability not specified are handled
       
  2807     			{
       
  2808     				if(pServiceData)
       
  2809 					{
       
  2810 						if(!stackPop)
       
  2811 			    		{
       
  2812 				    		stackPop = ETrue;
       
  2813 							CleanupStack::Pop(pServiceData);	
       
  2814 			    		}
       
  2815 		    			pServiceData->CleanUpMetaData();
       
  2816 						delete pServiceData;
       
  2817 						pServiceData = NULL;
       
  2818 					}	
       
  2819 					
       
  2820 					status = KLiwMetaDataInvalidFormat;
       
  2821     			}
       
  2822 	    	}	    		
       
  2823     		
       
  2824     		for (TInt idx = 0; idx < infoArrayPlugin.Count(); idx++)
       
  2825             {
       
  2826             	// currently assumed that implementations managed by plugins cannot be in ROM
       
  2827             	if (aItem->Options() & LIW_OPTIONS_ROM_ONLY) 
       
  2828                 {
       
  2829                 continue;
       
  2830                 }
       
  2831             }
       
  2832             
       
  2833             if(!stackPop)
       
  2834             {
       
  2835             	CleanupStack::Pop(pServiceData);	
       
  2836             }
       
  2837             
       
  2838             CleanupStack::Pop(pXmlHandler);
       
  2839             
       
  2840             if(pXmlHandler)
       
  2841 			{
       
  2842 				delete pXmlHandler;
       
  2843 			}			
       
  2844 
       
  2845 	        
       
  2846         } //end of for loop
       
  2847         
       
  2848     	if(pChosenImpl)
       
  2849 		{
       
  2850 		 	RArray<TCapability> provCaps;
       
  2851 		 	TFileName provResourcePath;
       
  2852 	    	GetCapabilitiesL(provCaps,pServiceData->GetMetaData());	    	
       
  2853 	    	  		
       
  2854 	    	TInt isAllowed(KErrNone);
       
  2855 	    	
       
  2856 	    	if(aScriptSession)
       
  2857 	    	    {
       
  2858 	    	    if(aScriptSession->PromptOption() == RTPROMPTUI_PROVIDER)
       
  2859 	    	    	{
       
  2860 	    	    		GetProviderResourceFile(provResourcePath, pServiceData->GetMetaData());
       
  2861 	    	        isAllowed = aScriptSession->IsAllowed(provCaps, pChosenImpl->ImplementationUid(), provResourcePath);	
       
  2862 	    	      }
       
  2863                 else
       
  2864                     isAllowed = aScriptSession->IsAllowed(provCaps);
       
  2865 	    	    }
       
  2866 	    		
       
  2867 	    	if(KErrNone==isAllowed)
       
  2868 		    {
       
  2869 				CLiwServiceIfBase* iface = iEcomMonitor->CreateImplementationL(
       
  2870 	            pChosenImpl->ImplementationUid());
       
  2871 
       
  2872 	            if (iface)
       
  2873 		        {
       
  2874 		            if(pServiceData)
       
  2875 		            {
       
  2876 		            	iface->iReserved=pServiceData;
       
  2877 		            }
       
  2878 		            	
       
  2879 		            
       
  2880 		            if (!IsCached(iface))
       
  2881 		            {
       
  2882 		                CleanupStack::PushL(iface);
       
  2883 		                status = KLiwServiceLoadSuccess;
       
  2884 		                iface->AddCriteria(aItem);
       
  2885 		                User::LeaveIfError(iProviders.Append( iface ));
       
  2886 		                CleanupStack::Pop(iface);
       
  2887 		                
       
  2888 		                aBinding->AddProviderL(iface, 
       
  2889 		                    pChosenImpl->ImplementationUid() == aItem->DefaultProvider());
       
  2890 		            }                           
       
  2891 		            else    
       
  2892 		            {
       
  2893 		                delete iface;
       
  2894 		                iface = NULL;                
       
  2895 		             }
       
  2896 		         }
       
  2897 		         
       
  2898 			  }
       
  2899 			  else
       
  2900 			  {
       
  2901 			  	  status = KLiwSecurityAccessCheckFailed;
       
  2902 				 
       
  2903 					if(pServiceData)
       
  2904 			      	{
       
  2905 			      		pServiceData->CleanUpMetaData();
       
  2906 			      		delete pServiceData;
       
  2907 			       		pServiceData = NULL;	
       
  2908 			      	}
       
  2909 			     
       
  2910 				//enhancement : Should assign this to the previous service data						      	
       
  2911 			  }
       
  2912 			  
       
  2913 			  provCaps.Close();
       
  2914 		  }
       
  2915 		  else
       
  2916           {
       
  2917           	//No Chosen implementation.. 
       
  2918           	
       
  2919           	if(pServiceData)  //This should ideally fail always
       
  2920           	{
       
  2921           		pServiceData->CleanUpMetaData();
       
  2922           		delete pServiceData;
       
  2923            		pServiceData = NULL;	
       
  2924           	}
       
  2925           } 
       
  2926           
       
  2927           if(0 == infoArray.Count())
       
  2928           	status = KLiwUnknown; 
       
  2929          
       
  2930          CleanupStack::PopAndDestroy(2);//infoArray and infoArrayPlugin 
       
  2931         }
       
  2932         else
       
  2933         {
       
  2934         	status = KLiwServiceAlreadyLoaded;
       
  2935         }
       
  2936     
       
  2937     return status;
       
  2938     
       
  2939     }
       
  2940 
       
  2941 
       
  2942 TBool CLiwServiceHandlerImpl::GetVersionRange(CLiwCriteriaItem* aItem,TReal& aMinVersion, TReal& aMaxVersion)
       
  2943 {
       
  2944 	TBool bFailed=EFalse;
       
  2945 	TLiwVariant metaDataVar;
       
  2946 	metaDataVar.PushL();
       
  2947 	
       
  2948 	aItem->GetMetaDataOptions(metaDataVar);
       
  2949 	
       
  2950 	const CLiwMap* metaDataMap = metaDataVar.AsMap();
       
  2951 	
       
  2952 	if(metaDataMap)
       
  2953 	{
       
  2954 	_LIT8(KRangeKey,"range");
       
  2955 	TLiwVariant rangeVar;
       
  2956 	rangeVar.PushL();
       
  2957 	
       
  2958 	if(metaDataMap->FindL(KRangeKey, rangeVar))
       
  2959 	{
       
  2960 		const CLiwList* pRangeList = rangeVar.AsList();
       
  2961 		if(pRangeList)
       
  2962 		{
       
  2963 			TLiwVariant verCheck;
       
  2964 			verCheck.PushL();
       
  2965 			_LIT8(KVersion,"ver");
       
  2966 			pRangeList->AtL(0,verCheck);
       
  2967 			
       
  2968 			if(EVariantTypeDesC8==verCheck.TypeId())
       
  2969 			{
       
  2970 				if(0==KVersion().CompareF(verCheck.AsData()))
       
  2971 				{
       
  2972 					TLiwVariant minVerVar, maxVerVar;
       
  2973 					minVerVar.PushL();
       
  2974 					maxVerVar.PushL();
       
  2975 					
       
  2976 					pRangeList->AtL(1,minVerVar);
       
  2977 					aMinVersion = minVerVar.AsTReal();
       
  2978 					
       
  2979 					if(minVerVar.AsTReal() < KDefVersion)
       
  2980 						bFailed = ETrue;
       
  2981 					
       
  2982 					pRangeList->AtL(2,maxVerVar);
       
  2983 					aMaxVersion = maxVerVar.AsTReal();
       
  2984 					
       
  2985 					if(maxVerVar.AsTReal() < aMinVersion && maxVerVar.AsTReal() != KUnspVersion)
       
  2986 						bFailed = ETrue;
       
  2987 					
       
  2988 					CleanupStack::Pop(&maxVerVar); 
       
  2989     				CleanupStack::Pop(&minVerVar); 
       
  2990     				minVerVar.Reset();
       
  2991 					maxVerVar.Reset();
       
  2992 				}
       
  2993 			}
       
  2994 			CleanupStack::Pop(&verCheck); 
       
  2995     		verCheck.Reset();
       
  2996 		}	
       
  2997 	}
       
  2998 	CleanupStack::Pop(&rangeVar); 
       
  2999     rangeVar.Reset();
       
  3000 	}
       
  3001 	
       
  3002 	CleanupStack::Pop(&metaDataVar); 
       
  3003     metaDataVar.Reset();
       
  3004 
       
  3005     return !bFailed;
       
  3006 }
       
  3007 
       
  3008 TBool CLiwServiceHandlerImpl::GetVersion(CLiwCriteriaItem* aItem,TReal& aVersion)
       
  3009 {
       
  3010 	TBool bFailed=EFalse;
       
  3011 	TLiwVariant metaDataVar;
       
  3012 	metaDataVar.PushL();
       
  3013 	
       
  3014 	aItem->GetMetaDataOptions(metaDataVar);
       
  3015 	
       
  3016 	const CLiwMap* metaDataMap = metaDataVar.AsMap();
       
  3017 	
       
  3018 	if(metaDataMap)
       
  3019 	{
       
  3020 	_LIT8(KExactKey,"exact");
       
  3021 	TLiwVariant exactVar;
       
  3022 	exactVar.PushL();
       
  3023 	
       
  3024 		if(metaDataMap->FindL(KExactKey, exactVar))
       
  3025 		{
       
  3026 			const CLiwList* pExactList = exactVar.AsList();
       
  3027 			if(pExactList)
       
  3028 			{
       
  3029 				TLiwVariant verCheck;
       
  3030 				verCheck.PushL();
       
  3031 				_LIT8(KVersion,"ver");
       
  3032 				pExactList->AtL(0,verCheck);
       
  3033 				
       
  3034 				if(EVariantTypeDesC8==verCheck.TypeId())
       
  3035 				{
       
  3036 					if(0==KVersion().CompareF(verCheck.AsData()))
       
  3037 					{
       
  3038 						TLiwVariant versionVar;
       
  3039 						versionVar.PushL();
       
  3040 						
       
  3041 						pExactList->AtL(1,versionVar);
       
  3042 						
       
  3043 	    				if((versionVar.AsTReal()) < KDefVersion)
       
  3044 	    				{
       
  3045 	    					bFailed = ETrue;
       
  3046 	    				}
       
  3047 	    				
       
  3048 	    				aVersion = versionVar.AsTReal();
       
  3049 						CleanupStack::Pop(&versionVar); 
       
  3050 	    				versionVar.Reset();
       
  3051 					}
       
  3052 				}
       
  3053 				CleanupStack::Pop(&verCheck); 
       
  3054 	    		verCheck.Reset();
       
  3055 			}	
       
  3056 		}
       
  3057 	
       
  3058 	CleanupStack::Pop(&exactVar); 
       
  3059     exactVar.Reset();
       
  3060 	}
       
  3061 	
       
  3062 	CleanupStack::Pop(&metaDataVar); 
       
  3063     metaDataVar.Reset();
       
  3064 	
       
  3065 	return !bFailed;
       
  3066 }
       
  3067 
       
  3068 // End of file