serviceproviders/sapi_serviceregistry/src/serviceinterface.cpp
changeset 19 989d2f495d90
child 37 5d0ec8b709be
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serviceproviders/sapi_serviceregistry/src/serviceinterface.cpp	Fri Jul 03 15:51:24 2009 +0100
@@ -0,0 +1,503 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#include "serviceinterface.h"
+
+// Including a copy of common constants for this compilation unit
+#include "serviceregistryservice.hrh"
+
+// Including utilities
+#include "serviceregistryutilities.h"
+
+#include "serviceregistryiterator.h"
+
+#include<hal.h>
+
+
+
+//constants for default and invalid versions
+const TReal KUnSpMaxVersion = 0.0;  
+const TReal KDefaultMinVersion = 1.0;
+//thread name
+_LIT(KThreadName,"ListThread");
+
+
+// -----------------------------------------------------------------------------
+// CServiceInterface::NewLC
+// Returns the instance of CServiceInterface.
+// -----------------------------------------------------------------------------
+//
+CServiceInterface* CServiceInterface::NewL()
+    {
+    CServiceInterface* self = new(ELeave) CServiceInterface();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CServiceInterface::~CServiceInterface
+// Destructor of class
+// -----------------------------------------------------------------------------
+//
+CServiceInterface::~CServiceInterface()
+    {
+    Cancel();
+    iThread.Close();            
+    delete iServiceHandler;  
+    iServiceHandler  =  NULL;
+
+    delete iServiceName;
+    iServiceName  =  NULL;
+
+    delete iInterfaceName;    
+    iInterfaceName =  NULL;
+    }
+
+
+void CServiceInterface :: RCriteriaArrayCleanup(TAny* aParam)
+    {
+    RCriteriaArray* ptr = reinterpret_cast<RCriteriaArray*>(aParam);
+    ptr->ResetAndDestroy();  
+    delete ptr;  
+    }
+// -----------------------------------------------------------------------------
+// CServiceInterface::ExecuteCmdL
+// Request handler method of interface class
+// -----------------------------------------------------------------------------
+//
+void CServiceInterface::ExecuteCmdL(const TDesC8& aCmdName,
+                                    const CLiwGenericParamList& aInParamList,
+                                    CLiwGenericParamList& aOutParamList,
+                                    TUint aCmdOptions ,
+                                    MLiwNotifyCallback* aCallBack)
+    {
+    TInt errCode(KErrNone);
+
+    // Process the command.
+    TRAP( errCode, ProcessCommandL(aCmdName, 
+                                   aInParamList, 
+                                   aOutParamList, 
+                                   aCmdOptions, 
+                                   aCallBack));
+    // Checking error code in here.
+    // If any error has been occurred then it is inserted into output list.
+    
+    
+    if(errCode != KErrNone)    
+        {
+        TServiceRegistryUtilities utils;
+        TLiwVariant retErrCode;
+        retErrCode.Set(TInt32(utils.GetSapiErrorCode(errCode)));
+        TLiwGenericParam errTypeParam(KErrorCode, retErrCode);
+        aOutParamList.AppendL(errTypeParam);        
+        }
+    }
+// -----------------------------------------------------------------------------
+// CServiceInterface::ExecuteServiceCommandL
+// Request handler method of interface class
+// -----------------------------------------------------------------------------
+//
+void CServiceInterface::ExecuteServiceCommandL(const TDesC8& aCmdName,
+                                               const CLiwGenericParamList& aInParamList,
+                                               CLiwGenericParamList& aOutParamList,
+                                               TUint aCmdOptions ,
+                                               MLiwNotifyCallback* aCallBack)
+    {
+    ExecuteCmdL(aCmdName, 
+                aInParamList, 
+                aOutParamList, 
+                aCmdOptions, 
+                aCallBack);
+    }
+
+
+// -----------------------------------------------------------------------------
+// CServiceInterface::ProcessCommandL
+// Method that processes calls of interface class
+// -----------------------------------------------------------------------------
+//
+void CServiceInterface::ProcessCommandL(const TDesC8& aCmdName,
+                                        const CLiwGenericParamList& aInParamList,
+                                        CLiwGenericParamList& aOutParamList,
+                                        TUint aCmdOptions ,
+                                        MLiwNotifyCallback* aCallBack)
+    {
+    TInt32 transactionID(aCallBack->GetTransactionID());
+
+    if(aCmdName.CompareF(KGetList) == 0)
+        {
+        // If requesting asynchronous service
+        if (aCmdOptions & KLiwOptASyncronous) // Asynchronous request
+            {
+            // Asynchronous request is supported
+            if (aCallBack) // Callback object must be passed
+                {
+                GetListL(aInParamList, aOutParamList, transactionID, aCallBack);
+                }
+            else
+                {
+                // Asynchronous request did not have callback object available                                
+                User::Leave(KErrArgument);
+                }
+            }
+            else 
+            {
+            // Synchronous request not supported for this method.            
+            User::Leave(KErrNotSupported);
+            }
+        }//GetList
+    else if(aCmdName.CompareF(KCmdCancel) == 0)
+        {
+        // TServiceRegistryUtilities utility class instance
+        TServiceRegistryUtilities utils;
+        TInt32 transID(utils.ConvertInputInt32L(aInParamList, 
+                                                KTransactionId));
+        if(KLiwOptCancel & aCmdOptions)
+            {                        
+            if(transID != iTransactionId)
+                {               
+                User::Leave(KErrNotFound);
+                }            
+            Cancel();
+            aOutParamList.AppendL(TLiwGenericParam(KErrorCode, 
+                                  TLiwVariant((TInt32)SErrNone)));    
+            }
+        else
+            {           
+            User::Leave(KErrNotSupported);
+            }
+        }//Cancel
+    else
+        {        
+        User::Leave(KErrNotSupported);//Command is not supported
+        }
+    // Sending transaction ID back to the client in case of an successful asynchronous call
+    if (aCallBack && aCmdOptions == KLiwOptASyncronous)
+        {
+        aOutParamList.AppendL(TLiwGenericParam(KTransactionId, 
+                              TLiwVariant((TInt32)transactionID)));
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CServiceInterface::CServiceInterface
+// Constructor of class
+// -----------------------------------------------------------------------------
+//
+CServiceInterface::CServiceInterface()
+                       :CActive(EPriorityStandard),
+                        iTransactionId(0),
+                        iServiceName(NULL),
+                        iInterfaceName(NULL),
+                        iMinVersion(KUnSpMaxVersion),
+                        iMaxVersion(KUnSpMaxVersion),
+                        iInParamList(NULL),
+                        iServiceHandler(NULL)                        
+    {
+    CActiveScheduler::Add(this);
+    }
+
+// -----------------------------------------------------------------------------
+// CServiceInterface::ConstructL
+// Two-phased constructor of class
+// -----------------------------------------------------------------------------
+//
+void CServiceInterface::ConstructL()
+    {
+    iServiceHandler = CLiwServiceHandler :: NewL();
+    iServiceName =  KNullDesC8().Alloc();
+    iInterfaceName = KNullDesC8().Alloc();
+    }
+    
+// -----------------------------------------------------------------------------
+// CServiceInterface::ListServiceProvidersL
+// This class is called once the async request is complete 
+// It puts the iterator into the ouputlist and calls the HnadleNotifyL.
+// -----------------------------------------------------------------------------
+//    
+void CServiceInterface :: ListServiceProvidersL(TInt32 aError)
+    {
+    CLiwGenericParamList* eventParamList = CLiwGenericParamList::NewL();
+    CleanupStack::PushL(eventParamList);
+          
+    TInt event = KLiwEventError;    
+                                                       
+    eventParamList->AppendL(TLiwGenericParam(KErrorCode, 
+                            TLiwVariant(aError)));
+    if(aError == KErrNone)
+        {    
+        event =  KLiwEventCompleted;       
+        eventParamList->AppendL(TLiwGenericParam(KReturnValue, 
+                                TLiwVariant(iIterator)));                             
+        iIterator->DecRef(); 
+        }                            
+                                     
+    TRAPD(err, iCallback->HandleNotifyL((TInt32)iTransactionId, 
+                                         event, 
+                                         *eventParamList, 
+                                         *iInParamList));
+                                                
+    //eventParamList->Reset();                                                                                                                                                                        
+    CleanupStack::PopAndDestroy(eventParamList);          
+    }
+   
+   
+
+// -----------------------------------------------------------------------------
+// This funtion runs as a part of the thread and fetches the list of providers 
+// creates the iterator to the list.
+// -----------------------------------------------------------------------------
+//
+
+void GetListProviderL(CServiceInterface* aInterface)
+    {             
+    CLiwMap* pMetaDataMap = NULL;    // map with key as "range" and value as a List
+    CLiwList* pRangeList = NULL;                                              
+    RCriteriaArray* interest = new(ELeave) RCriteriaArray;
+    RCriteriaArray* providerList = new(ELeave) RCriteriaArray;
+
+    CleanupStack::PushL(TCleanupItem(CServiceInterface::RCriteriaArrayCleanup, interest));
+    CleanupStack::PushL(TCleanupItem(CServiceInterface::RCriteriaArrayCleanup, providerList));
+        
+    if(aInterface->iServiceName->CompareF(KNullDesC8) == 0)
+        {
+        delete aInterface->iServiceName; 
+        aInterface->iServiceName = KWild().Alloc();                           
+        }
+    if(aInterface->iInterfaceName->CompareF(KNullDesC8) == 0)
+        {
+        delete aInterface->iInterfaceName;
+        aInterface->iInterfaceName = KWild().Alloc();            
+        }
+                
+    //To Query for a list of all the LIW providers present.        
+    CLiwCriteriaItem* criteria = CLiwCriteriaItem::NewL(1, 
+                                                        *aInterface->iInterfaceName, 
+                                                        *aInterface->iServiceName);
+    //delete the member variables so that they cab be used again
+    // for the next call.
+    
+    delete aInterface->iServiceName;
+    aInterface->iServiceName = KNullDesC8().Alloc();
+    delete aInterface->iInterfaceName;
+    aInterface->iInterfaceName = KNullDesC8().Alloc();
+                                                        
+    CleanupStack::PushL(criteria);
+        
+    if(aInterface->iMinVersion != KUnSpMaxVersion || aInterface->iMaxVersion != KUnSpMaxVersion)
+        {        
+        pMetaDataMap = CLiwDefaultMap::NewL();    // map with key as "range" and value as a List
+        CleanupStack::PushL(pMetaDataMap);
+        
+        pRangeList = CLiwDefaultList::NewL();    // List where the values such as "ver" , minimum and maximum will be stored
+        CleanupStack::PushL(pRangeList);
+                                                   
+        pRangeList->AppendL(TLiwVariant(KVersion)); // "ver" is the string representing VERSION information in metadata                
+        
+        pRangeList->AppendL(TLiwVariant(aInterface->iMinVersion)); // minimum range - The service should contain version only above this    
+        
+        pRangeList->AppendL(TLiwVariant(aInterface->iMaxVersion)); // maximum range - The service should contain version only below this    
+                           
+        pMetaDataMap->InsertL(KRange, pRangeList);         // "range" is set as key and the value is the List created above
+    	criteria->SetMetaDataOptions(pMetaDataMap);		
+    	
+        pRangeList->DecRef();                              // Decrementing the reference of the List
+        pMetaDataMap->DecRef();                            // Decrementing the reference of the Map 
+                  
+        CleanupStack::Pop(pRangeList);
+        CleanupStack::Pop(pMetaDataMap);
+        }
+    //reset the version members to unspecified.
+    aInterface->iMinVersion = KUnSpMaxVersion;
+    aInterface->iMaxVersion = KUnSpMaxVersion;
+    
+    //Presently this value is changed to differentiate LIW Providers from other Ecom plug-ins.    
+    criteria->SetServiceClass(TUid::Uid(KLiwClassBase));        
+                  
+    interest->AppendL(criteria);
+    CleanupStack::Pop(criteria); 
+                     
+    aInterface->iServiceHandler->QueryImplementationL(*interest, *providerList); 
+               
+    aInterface->iIterator = CSvcRegIterator :: NewL();       
+    
+    aInterface->iIterator->SetProviderDataList(providerList);
+            
+    CleanupStack::Pop(providerList);    
+    CleanupStack::PopAndDestroy(interest); 
+    
+}
+
+
+// -----------------------------------------------------------------------------
+// Thread Function which calls the  GetListProviderL
+// -----------------------------------------------------------------------------
+// 
+TInt ThreadListProvider(TAny* aData)
+    {
+    CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack    
+    CServiceInterface* svcifc = reinterpret_cast<CServiceInterface*> (aData);
+    TRAPD(err, GetListProviderL(svcifc));    
+    delete cleanup;        
+    User::Exit(err);
+    return 0;
+    } 
+      
+// -----------------------------------------------------------------------------
+// CServiceInterface::GetListL
+// Gets the list of ServiceProviders.
+// -----------------------------------------------------------------------------
+//
+
+void  CServiceInterface::GetListL(const CLiwGenericParamList& aInParamList, 
+                                  CLiwGenericParamList&  aOutParamList, 
+                                  TInt32 aTransactionId, 
+                                  MLiwNotifyCallback* aCallBack)                                   
+    {
+    TInt pos =  0;    
+    TLiwVariant minver;
+    TLiwVariant maxver;
+    TLiwVariant serviceName;    
+    TLiwVariant interfaceName;    
+    
+    const CLiwMap* pMap = NULL;
+    const TLiwGenericParam* paramFilterMap = NULL;
+    
+    iCallback =  aCallBack;
+    iTransactionId =  aTransactionId;    
+                                                                                      
+    paramFilterMap  = aInParamList.FindFirst(pos, KParamFilter);
+    
+    if(paramFilterMap)
+        {
+        pMap = paramFilterMap->Value().AsMap(); 
+        if(pMap)
+            {                           
+            if( pMap->FindL(KServiceName, serviceName))
+                {
+                if ( serviceName.TypeId() != LIW::EVariantTypeDesC )
+                    {
+                    serviceName.Reset();
+                    User::Leave( KErrArgument );
+                    }
+                delete iServiceName;
+                iServiceName = NULL;
+                iServiceName = HBufC8::NewL(serviceName.AsDes().Length());
+                iServiceName->Des().Copy(serviceName.AsDes());    
+                }            
+            if( pMap->FindL(KInterfaceName, interfaceName))
+                {
+                if ( interfaceName.TypeId() != LIW::EVariantTypeDesC )
+                    {
+                    serviceName.Reset();
+                    interfaceName.Reset();     
+                    User::Leave( KErrArgument );
+                    }
+                delete iInterfaceName;
+                iInterfaceName = NULL;
+                iInterfaceName = HBufC8::NewL(interfaceName.AsDes().Length());
+                iInterfaceName->Des().Copy(interfaceName.AsDes());    
+                }                              
+            if( pMap->FindL(KMinVersion, minver))
+                {
+                if ( minver.TypeId() != LIW::EVariantTypeTReal && minver.TypeId() != LIW::EVariantTypeTInt32)
+                    {
+                    minver.Reset();
+                    serviceName.Reset();
+                    interfaceName.Reset();     
+                    User::Leave( KErrArgument );
+                    }
+                iMinVersion = minver.AsTReal();
+                }
+            if( pMap->FindL(KMaxVersion, maxver))
+               { 
+               if ( maxver.TypeId() != LIW::EVariantTypeTReal  && maxver.TypeId() != LIW::EVariantTypeTInt32 )
+                   {
+                   minver.Reset();
+                   maxver.Reset();
+                   serviceName.Reset();
+                   interfaceName.Reset();     
+                   User::Leave( KErrArgument );
+                   }
+               iMaxVersion = maxver.AsTReal();
+               //set the min version to default only if max version is specified.                
+               if(iMinVersion == KUnSpMaxVersion)
+                   iMinVersion = KDefaultMinVersion;  
+               }                               
+        if(iMaxVersion != KUnSpMaxVersion)
+            {
+             if(iMaxVersion < iMinVersion)
+                {
+                minver.Reset();
+                maxver.Reset();
+                serviceName.Reset();
+                interfaceName.Reset();               
+                User::Leave(KErrArgument);    
+                }                 
+            }                      
+        } 
+    else
+        {
+        minver.Reset();
+        maxver.Reset();
+        serviceName.Reset();
+        interfaceName.Reset();               
+        User::Leave(KErrArgument);  
+        }
+        }        
+    minver.Reset();
+    maxver.Reset();  
+    serviceName.Reset();
+    interfaceName.Reset();     
+           
+    if(!IsActive())
+        {
+        User::LeaveIfError(iThread.Create(KThreadName, 
+                           ThreadListProvider, 
+                           KDefaultStackSize,
+                           &User::Allocator(),
+                           this));
+        }
+    else
+        {
+        User::Leave(KErrInUse);
+        }            
+    iStatus = KRequestPending;        
+    SetActive();    
+    iThread.Resume();          
+    iThread.Logon(iStatus);      
+    // append the error code to the outputlist.
+    aOutParamList.AppendL(TLiwGenericParam(KErrorCode, 
+                          TLiwVariant(TInt32(SErrNone))));
+    }
+
+void CServiceInterface :: DoCancel()
+    {
+    iThread.Kill(KErrNone); 
+    iThread.Close();
+    }
+    
+    
+void CServiceInterface :: RunL()
+    {
+    iThread.Close();           
+    ListServiceProvidersL(iStatus.Int());        
+    }    
+