cmmanager/cmmgr/cmmserver/src/cmmcache.cpp
changeset 44 a0c4ceac30d0
parent 40 c5b848e6c7d1
child 61 8b0c979bbe8c
--- a/cmmanager/cmmgr/cmmserver/src/cmmcache.cpp	Thu Jun 24 11:36:05 2010 +0300
+++ b/cmmanager/cmmgr/cmmserver/src/cmmcache.cpp	Fri Jul 09 10:25:55 2010 +0300
@@ -125,6 +125,9 @@
     iBearerPriorityCache = NULL;
     iCurrentTemporaryId = KTemporaryIdCounterStart;
 
+    iSnapTableId = 0;
+    iSnapMetadataTableId = 0;
+
     OstTraceFunctionExit0( DUP1_CCMMCACHE_CCMMCACHE_EXIT );
     }
 
@@ -144,6 +147,41 @@
     iListenerManager = CCmmListenerManager::NewL( this );
     iInstanceMapping = CCmmInstanceMapping::NewL( *this );
 
+    // Create CommsDat listeners to detect changes to the database from external sources.
+    RArray<TUint32> tableIdArray;
+    CleanupClosePushL( tableIdArray );
+
+    iSnapTableId = iCmManagerImpl->TableId( ECmmDbSnapRecord );
+    iSnapMetadataTableId = iCmManagerImpl->TableId( ECmmDestMetadataRecord );
+
+    // Instancemapping needs notifications on following tables.
+    tableIdArray.Append( CommsDat::KCDTIdIAPRecord );
+    tableIdArray.Append( CommsDat::KCDTIdVPNServiceRecord );
+    tableIdArray.Append( iSnapTableId );
+    tableIdArray.Append( iSnapMetadataTableId );
+
+    // Destinations need notifications on following tables.
+    tableIdArray.Append( CommsDat::KCDTIdNetworkRecord );
+    tableIdArray.Append( CommsDat::KCDTIdAccessPointRecord );
+    // Destination metadata table was already added.
+
+    // Connection methods need notifications on following tables.
+    TInt pluginCount( iPlugins->Count() );
+    if ( pluginCount )
+        {
+        ( *iPlugins )[0]->GetGenericTableIdsToBeObservedL( tableIdArray );
+        for( TInt i = 0; i < pluginCount; i++ )
+            {
+            ( *iPlugins )[i]->GetBearerTableIdsToBeObservedL( tableIdArray );
+            }
+        }
+
+    for ( TInt i = 0; i < tableIdArray.Count(); i++ )
+        {
+        iListenerManager->AddListenerL( tableIdArray[i] );
+        }
+    CleanupStack::PopAndDestroy( &tableIdArray );
+
     OstTraceFunctionExit0( CCMMCACHE_CONSTRUCTL_EXIT );
     }
 
@@ -270,14 +308,17 @@
     if ( !aDestinationInstance )
         {
         // Check connection method exists in database.
-        validAttributes = iInstanceMapping->ValidConnMethodId( aConnMethodId ); // Embedded destinations not included.
+        // Embedded destinations not included.
+        validAttributes = iInstanceMapping->ValidConnMethodId( aConnMethodId );
         }
     else
         {
         // Check connection method is inside the destination.
-        if ( aDestinationInstance->ValidConnMethodIdInDestinationIncludeEmbedded( aConnMethodId ) )
+        if ( aDestinationInstance->
+                ValidConnMethodIdInDestinationIncludeEmbedded( aConnMethodId ) )
             {
-            // Check connection method (can be embedded destination too) exists in database.
+            // Check connection method (can be embedded destination too)
+            // exists in database.
             if ( iInstanceMapping->ValidConnMethodId( aConnMethodId ) ||
                     iInstanceMapping->ValidDestinationId( aConnMethodId ) )
                 {
@@ -296,9 +337,17 @@
     TInt index = FindConnMethodFromCache( aConnMethodId );
     if ( index != KErrNotFound )
         {
+        // Update data from commsdat if necessary.
+        if ( iConnMethodArray[index]->GetRecordStatus() == ECmmRecordStatusExpired )
+            {
+            iConnMethodArray[index]->ReloadPluginDataIfNeededL();
+            // CopyDataL() will set the internal state of aConnMethodInstance.
+            }
+
         // Already open in cache. Copy the connection method data to session
         // instance.
-        aConnMethodInstance.CopyDataL( iConnMethodArray[index] ); // Will increase reference counter.
+        // Will increase reference counter.
+        aConnMethodInstance.CopyDataL( iConnMethodArray[index] );
         }
     else
         {
@@ -339,7 +388,15 @@
         return;
         }
 
-    iConnMethodArray[index]->RefreshConnMethodInstanceL( aConnMethodInstance );
+    iConnMethodArray[index]->ReloadPluginDataIfNeededL();
+    if ( iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusValid
+            || iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusToBeDeleted )
+        {
+        iConnMethodArray[index]->GetPlugin()->GetPluginDataL( 
+                aConnMethodInstance.GetPluginDataInstance() );
+        }
+    // Internal state need to be set to the same state as after a successfull update.
+    aConnMethodInstance.UpdateSuccessful();
 
     OstTraceFunctionExit0( DUP1_CCMMCACHE_REFRESHCONNMETHODL_EXIT );
     }
@@ -475,7 +532,7 @@
     }
 
 // ---------------------------------------------------------------------------
-// Re-loads a destination record if needed and copies the latest version to
+// Reloads a destination record if needed and copies the latest version to
 // the session instance given as parameter.
 // ---------------------------------------------------------------------------
 //
@@ -1618,16 +1675,120 @@
 // needed.
 // ---------------------------------------------------------------------------
 //
-void CCmmCache::DbChangeDetected( const TUint32 aTableId )
+void CCmmCache::DbChangeDetectedL( const TUint32 aTableId )
     {
     OstTraceFunctionEntry0( CCMMCACHE_DBCHANGEDETECTED_ENTRY );
 
-    (void)aTableId; //TODO
-    // Flag the table as: currently not up-to-date
+    if ( aTableId == iSnapMetadataTableId )
+        {
+        for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
+            {
+            iDestinationArray[i]->NotifyRecordChange( ECmmDestMetadataRecord );
+            }
+        }
+    else if ( aTableId == CommsDat::KCDTIdNetworkRecord )
+        {
+        // Affects destinations.
+        for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
+            {
+            iDestinationArray[i]->NotifyRecordChange( ECmmDestNetworkRecord );
+            }
+        }
+    else if ( aTableId == CommsDat::KCDTIdAccessPointRecord )
+        {
+        // Affects destinations.
+        for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
+            {
+            iDestinationArray[i]->NotifyRecordChange( ECmmDestApRecord );
+            }
+        }
+
+    // Notify Connection Methods about the table changes in CommsDat.
+    NotifyPluginsForTableChangesL( aTableId );
+
+    // Update instancemapping.
+    iInstanceMapping->RefreshL();
+
     OstTraceFunctionExit0( CCMMCACHE_DBCHANGEDETECTED_EXIT );
     }
 
 // ---------------------------------------------------------------------------
+// Informs all the loaded iaps if something related to their tables
+// changed in commsdat.
+// ---------------------------------------------------------------------------
+//
+void CCmmCache::NotifyPluginsForTableChangesL( const TUint32 aTableId )
+    {
+    OstTraceFunctionEntry0( CCMMCACHE_NOTIFYPLUGINSFORTABLECHANGESL_ENTRY );
+
+    if ( iConnMethodArray.Count() )
+        {
+        RArray<TUint32> tableIdArray;
+        CleanupClosePushL( tableIdArray );
+
+        // Check if change concerns some table generic for all iaps
+        ( *iPlugins )[0]->GetGenericTableIdsToBeObservedL( tableIdArray );
+        TBool generic( EFalse );
+        for( TInt i = 0; i < tableIdArray.Count(); i++ )
+            {
+            if ( aTableId == tableIdArray[i] )
+                {
+                generic = ETrue;
+                break;
+                }
+            }
+
+        if ( generic )
+            {
+            // generic-->Notify all iaps
+            for( TInt i = 0; i < iConnMethodArray.Count(); i++ )
+                {
+                iConnMethodArray[i]->NotifyRecordChange( aTableId );
+                }
+            }
+        else
+            {
+            // Not generic: Check bearer specific tables
+            RArray<TUint32> affectedBearersArray;
+            CleanupClosePushL( affectedBearersArray );
+            for( TInt i = 0; i < iPlugins->Count(); i++ )
+                {
+                tableIdArray.Reset();
+                ( *iPlugins )[i]->GetBearerTableIdsToBeObservedL( tableIdArray );
+                TInt idCount = tableIdArray.Count();
+                for( TInt j = 0; j < idCount; j++ )
+                    {
+                    if ( aTableId == tableIdArray[j] )
+                        {
+                        // Save the bearer type id which is affected
+                        affectedBearersArray.AppendL(
+                                ( *iPlugins )[i]->GetBearerInfoIntL(
+                                        CMManager::ECmBearerType ) );
+                        }
+                    }
+                }
+
+            // Go through all the loaded iaps and notify all the iaps
+            // which have the same bearer type saved above
+            for( TInt i = 0; i < iConnMethodArray.Count(); i++ )
+                {
+                for( TInt j = 0; j < affectedBearersArray.Count(); j++ )
+                    {
+                    if ( iConnMethodArray[i]->GetBearerType() == affectedBearersArray[j] )
+                        {
+                        iConnMethodArray[i]->NotifyRecordChange( aTableId );
+                        break;
+                        }
+                    }
+                }
+            CleanupStack::PopAndDestroy( &affectedBearersArray );
+            }
+        CleanupStack::PopAndDestroy( &tableIdArray );
+        }
+    OstTraceFunctionExit0( CCMMCACHE_NOTIFYPLUGINSFORTABLECHANGESL_EXIT );
+    }
+
+// ---------------------------------------------------------------------------
 // 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.
@@ -1639,6 +1800,15 @@
 
     (void)aTableId; //TODO
     // Flag the table as: permanently not up-to-date
+
+    //TODO, How to do this?
+    // Implement some 'status locked' flags that are always checked before changing status back to 'loaded' after reading database?
+    // Or move record status info to CCmmCache-class?
+    // What about plugins?
+	// Or just ignore errors with notifiers?
+
+    // For now, just ignore errors.
+
     OstTraceFunctionExit0( CCMMCACHE_DBCHANGEERROR_EXIT );
     }
 
@@ -2128,13 +2298,15 @@
 
     // Find out the connection method bearer type.
     TUint32 bearerType( 0 );
-    User::LeaveIfError( iInstanceMapping->GetConnMethodBearerType( aConnMethodId, bearerType ) );
+    User::LeaveIfError( iInstanceMapping->
+            GetConnMethodBearerType( aConnMethodId, bearerType ) );
 
     // Check bearer type support and create plugin instance.
     CCmPluginBaseEng* plugin = NULL;
     for ( TInt i = 0; i < iPlugins->Count(); i++ )
         {
-        if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == bearerType )
+        if ( ( *iPlugins )[i]->GetBearerInfoIntL(
+                CMManager::ECmBearerType ) == bearerType )
             {
             TCmPluginInitParam pluginParams( Session() );
             plugin = ( *iPlugins )[i]->CreateInstanceL( pluginParams );
@@ -2181,7 +2353,8 @@
     if ( index != KErrNotFound )
         {
         // Already open in cache. Copy the connection method to session instance.
-        cmInstance->CopyDataL( iConnMethodArray[index] ); // Will increase reference counter.
+        // Will increase reference counter.
+        cmInstance->CopyDataL( iConnMethodArray[index] );
         }
     else
         {
@@ -2215,7 +2388,8 @@
     if ( index != KErrNotFound )
         {
         // Already open in cache. Copy the connection method to session instance.
-        cmInstance->CopyDataL( iConnMethodArray[index] ); // Will increase reference counter.
+        // Will increase reference counter.
+        cmInstance->CopyDataL( iConnMethodArray[index] );
         }
     else
         {
@@ -2249,7 +2423,8 @@
     if ( index != KErrNotFound )
         {
         // Already open in cache. Copy the connection method to session instance.
-        cmInstance->CopyDataL( iConnMethodArray[index] ); // Will increase reference counter.
+        // Will increase reference counter.
+        cmInstance->CopyDataL( iConnMethodArray[index] );
         }
     else
         {