cmmanager/cmmgr/cmmserver/src/cmmcache.cpp
changeset 66 ed07dcc72692
parent 53 4af712113915
--- a/cmmanager/cmmgr/cmmserver/src/cmmcache.cpp	Fri Sep 17 08:32:43 2010 +0300
+++ b/cmmanager/cmmgr/cmmserver/src/cmmcache.cpp	Mon Oct 04 00:43:42 2010 +0300
@@ -457,7 +457,18 @@
         }
     if ( !plugin )
         {
-        User::Leave( KErrArgument );
+        TInt index = RefreshPluginL( aBearerType );
+        if ( index < 0 || index >= iPlugins->Count() )
+            {
+            User::Leave( KErrArgument );
+            }
+        else
+            {
+            TCmPluginInitParam pluginParams( Session() );
+            plugin = ( *iPlugins )[index]->CreateInstanceL( pluginParams );
+            CleanupStack::PushL( plugin );
+            plugin->CreateNewL( aConnMethodId );
+            }
         }
 
 
@@ -1789,6 +1800,61 @@
     }
 
 // ---------------------------------------------------------------------------
+// Try to load unknown plugin dynamically during running-time. Some plugin
+// (e.g., VPN) might be installed after CmManager starts up. So, try to load
+// it. Only one plugin can be possibly loaded in a time.
+// ---------------------------------------------------------------------------
+//
+TInt CCmmCache::RefreshPluginL( const TUint32 aBearerType )
+    {
+    OstTraceFunctionEntry0( CCMMCACHE_REFRESHPLUGIN_ENTRY );
+
+    TInt ret( KErrNotFound );
+    
+    // Get a list of all the bearer types.
+    RPointerArray<CImplementationInformation> implArray;
+    CmmCleanupResetAndDestroyPushL( implArray );
+    REComSession::ListImplementationsL( TUid::Uid( KCMPluginInterfaceUid ), implArray );
+
+    CCmPluginBaseEng* plugin = NULL;
+    for ( TInt i = 0; i < implArray.Count(); i++ )
+        {
+        TUid uid = ( implArray )[i]->ImplementationUid();
+        
+        if ( uid.iUid == aBearerType )
+            {
+            TCmPluginInitParam params( iTrans->Session() );
+            
+            TRAPD( err, plugin = STATIC_CAST( CCmPluginBaseEng*, REComSession::CreateImplementationL(
+                    uid,
+                    _FOFF( CCmPluginBaseEng, iDtor_ID_Key ),
+                    ( TAny* )&params ) ) );
+            
+            if ( !err )
+                {
+                CleanupStack::PushL( plugin );
+                
+                // We may not think the priority position in the plugin array for this newly loaded plugin
+                // and just simply append it in the end of the plugin array
+                iPlugins->AppendL( plugin );
+                
+                ret = iPlugins->Count() - 1;
+                
+                CleanupStack::Pop( plugin );
+                }
+ 
+            // Don't need to go further in the for loop
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &implArray );
+
+    OstTraceFunctionExit0( CCMMCACHE_REFRESHPLUGIN_EXIT );
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
 // Tells the cache that an error has occured with a database listener. Any
 // reads to this table need go through the database, since cache can't know if
 // it has up-to-date information.