Revision: 201021 RCL_3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 09 Jun 2010 10:09:20 +0300
branchRCL_3
changeset 14 3e156c80c15d
parent 13 4a4892eec172
child 16 9422ed56ee45
Revision: 201021 Kit: 2010123
clfwrapper/ClientSrc/CCLFServerProxy.cpp
harvester/client/src/harvesterclient.cpp
harvester/harvesterplugins/VideoPlugin/data/200009f9.rss
harvester/harvesterplugins/VideoPlugin/inc/harvestervideoplugin.h
harvester/harvesterplugins/VideoPlugin/src/harvestervideoplugin.cpp
harvester/harvesterplugins/WMVPlugin/data/2000B431.rss
harvester/monitorplugins/mdsfileserverplugin/src/mdsfileserverplugin.cpp
harvester/server/inc/harvesterao.h
harvester/server/src/harvesterao.cpp
inc/mdscommoninternal.h
metadataengine/client/src/mdeobject.cpp
metadataengine/data/schema.mde
metadataengine/server/inc/mdsmaintenanceengine.h
metadataengine/server/src/mdsmaintenanceengine.cpp
metadataengine/server/src/mdsserver.cpp
sis/mds/mds_stub.sis
sis/mds/package.pkg
sis/mds/package_separate.pkg
sis/mds/stub.pkg
--- a/clfwrapper/ClientSrc/CCLFServerProxy.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/clfwrapper/ClientSrc/CCLFServerProxy.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -32,7 +32,7 @@
 // CONSTANTS
 const TInt KCLFDefaultBufferLength( 64 );
 const TInt KCLFDefaultArrayGranularity( 4 );
-const TInt KCLFExtensionArrayGranularity( 50 );
+const TInt KCLFExtensionArrayGranularity( 51 );
 
 _LIT( KCLFDriveLetterFormatString, ":\\" );
 const TInt KCLFDriveC( 'C' );
@@ -93,6 +93,7 @@
 _LIT( KExtensionWmv,    "wmv" );
 _LIT( KExtensionAvi,    "avi" );
 _LIT( KExtensionDivx,    "divx" );
+_LIT( KExtensionAsf,    "asf" );
 
 // ======== MEMBER FUNCTIONS ========
 
@@ -1285,6 +1286,7 @@
     iExtensionArray->InsertIsqL( KExtensionWmv );
     iExtensionArray->InsertIsqL( KExtensionAvi );
     iExtensionArray->InsertIsqL( KExtensionDivx );
+    iExtensionArray->InsertIsqL( KExtensionAsf );
     }
 
 //  End of File
--- a/harvester/client/src/harvesterclient.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/client/src/harvesterclient.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -126,6 +126,8 @@
 
     iHEO = NULL;
     
+    iSessionWatcher = NULL;
+    
     return err;
     }
 
@@ -166,6 +168,7 @@
     WRITELOG( "RHarvesterClient::Close()" );
     
     delete iSessionWatcher;
+    iSessionWatcher = NULL;
     
     // cancels Harvest Complete request if it exist at server
     UnregisterHarvestComplete();
@@ -202,8 +205,8 @@
 
     if ( iHarvesterClientAO )
         {
-       iHarvesterClientAO->SetObserver( aObserver );
-       }
+        iHarvesterClientAO->SetObserver( aObserver );
+        }
 	iObserver = aObserver;
     }
 
--- a/harvester/harvesterplugins/VideoPlugin/data/200009f9.rss	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/harvesterplugins/VideoPlugin/data/200009f9.rss	Wed Jun 09 10:09:20 2010 +0300
@@ -42,7 +42,7 @@
 					version_no = 1;
 					display_name = "Harvester video plugin";
 					default_data = "Video Audio";
-					opaque_data = "mp4 mpg4 mpeg4 m4v m4a 3gp 3gpp rm rv rmvb 3g2 avi mkv ra wmv divx";
+					opaque_data = "mp4 mpg4 mpeg4 m4v m4a 3gp 3gpp rm rv rmvb 3g2 avi mkv ra wmv divx asf";
           rom_only = 0;
 					}
 				};
--- a/harvester/harvesterplugins/VideoPlugin/inc/harvestervideoplugin.h	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/harvesterplugins/VideoPlugin/inc/harvestervideoplugin.h	Wed Jun 09 10:09:20 2010 +0300
@@ -221,6 +221,12 @@
 		void GetMp4Type( RFile64& aFile, TDes& aType );
 		
 		void GetRmTypeL( RFile64& aFile, TDes& aType );
+
+        TInt AddFileToBlackList( const TFileName& aFullName, const TUint32& aMediaId );
+
+        TInt RemoveFileFromBlackList( const TFileName& aFullName, const TUint32& aMediaId );
+
+        TInt GetFileFullNameAndMediaId( const RFile64& aFile, TFileName& aFullName, TUint32& mediaId);
 	
 		const THarvestingHandling* FindHandler( const TDesC& aUri );
 		
--- a/harvester/harvesterplugins/VideoPlugin/src/harvestervideoplugin.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/harvesterplugins/VideoPlugin/src/harvestervideoplugin.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -52,6 +52,7 @@
 _LIT( KMimeTypeAudioMatroska, "audio/x-matroska");
 _LIT( KMimeTypeWmv, "video/x-ms-wmv");
 _LIT( KMimeTypeDivx, "video/x-hx-divx");
+_LIT( KMimeTypeAsf, "video/x-ms-asf");
 
 _LIT( KExtensionMp4,   "mp4" );
 _LIT( KExtensionMpg4,  "mpg4" );
@@ -69,6 +70,7 @@
 _LIT( KExtensionRa,     "ra" );
 _LIT( KExtensionWmv,     "wmv" );
 _LIT( KExtensionDivx,     "divx" );
+_LIT( KExtensionAsf,     "asf" );
 
 _LIT(KVideo, "Video");
 _LIT(KAudio, "Audio");
@@ -275,6 +277,13 @@
                     KMimeTypeWmv(), KMimeTypeWmv() ) ), 
             cmp ) );
 
+    // Asf
+    User::LeaveIfError( iMimeTypeMappings.InsertInOrder( THarvestingHandling(
+            KExtensionAsf(), KMimeTypeAsf(), 
+            TVideoMetadataHandling( TVideoMetadataHandling::EHexilMetadataHandling, KVideo(),
+                    KMimeTypeAsf(), KMimeTypeAsf() ) ), 
+            cmp ) );
+
     TFileName videos = PathInfo::VideosPath();
     
     TFileName phonePath = PathInfo::PhoneMemoryRootPath();
@@ -1146,6 +1155,16 @@
 void CHarvesterVideoPlugin::GetMp4Type( RFile64& aFile, TDes& aType )
     {
     WRITELOG( "CHarvesterVideoPlugin::GetMp4Mime - MP4ParseOpenFileHandle - start" );
+    TFileName tempName;
+    TUint32 mediaId( 0 );
+    TInt blackListError( KErrNone );
+
+    blackListError = GetFileFullNameAndMediaId( aFile, tempName, mediaId );
+    if( blackListError == KErrNone )
+        {
+        blackListError == AddFileToBlackList( tempName, mediaId );
+        }
+
     MP4Handle handle;
 
     MP4Err mp4err = MP4ParseOpenFileHandle64( &handle, &aFile );
@@ -1181,6 +1200,11 @@
     	aType.Copy( KVideo() );
     	}
 
+    if( blackListError == KErrNone )
+        {
+        RemoveFileFromBlackList( tempName, mediaId );
+        }
+
     MP4ParseClose( handle );
 	}
 #else
@@ -1196,27 +1220,14 @@
 	CHXMetaDataUtility* helixMetadata = CHXMetaDataUtility::NewL();
 	CleanupStack::PushL( helixMetadata );
 
-	TFileName tempName;
-	TUint32 mediaId( 0 );
-	TInt blackListError( KErrNone );
-	
-    if( iBlacklist )
+    TFileName tempName;
+    TUint32 mediaId( 0 );
+    TInt blackListError( KErrNone );
+    
+    blackListError = GetFileFullNameAndMediaId( aFile, tempName, mediaId );
+    if( blackListError == KErrNone )
         {
-        WRITELOG( "CHarvesterVideoPlugin::GetRmTypeL - Adding URI to blacklist" );
-        blackListError = aFile.FullName( tempName );
-        if( blackListError == KErrNone )
-            {
-            blackListError = iMediaIdUtil->GetMediaId( tempName, mediaId );
-            if( blackListError == KErrNone )
-                {
-                TTime modified ( 0 );
-                blackListError = iFs.Modified( tempName, modified );
-                if( blackListError == KErrNone )
-                    {
-                    iBlacklist->AddFile( tempName, mediaId, modified );
-                    }
-                }
-            }
+        AddFileToBlackList( tempName, mediaId );
         }
 	
 	TRAPD( err, helixMetadata->OpenFileL( aFile ) );
@@ -1259,7 +1270,7 @@
 			// "application/vnd.rn-realmedia" or "application/vnd.rn-realmedia-vbr"
 			if( MdsUtils::Find( *mime, KMimeTypeRm() ) != KErrNotFound )
 				{
-				WRITELOG1( "CHarvesterVideoPlugin::GetObjectType - mimetype %S. Object type Rm", mime );
+				WRITELOG1( "CHarvesterVideoPlugin::GetRmTypeL - mimetype %S. Object type Rm", mime );
 				if( possibleVideo )
 					{
 					aType.Copy( KVideo );
@@ -1273,7 +1284,7 @@
 				}
 			else if( MdsUtils::Find( *mime, KVideo() ) != KErrNotFound )
 				{
-				WRITELOG1( "CHarvesterVideoPlugin::GetObjectType - mimetype %S. Object type Video", mime );
+				WRITELOG1( "CHarvesterVideoPlugin::GetRmTypeL - mimetype %S. Object type Video", mime );
 				aType.Copy( KVideo );
 	
 				// use MIME with "video" substring, if file might be video
@@ -1284,7 +1295,7 @@
 				}
 			else if( MdsUtils::Find( *mime, KAudio() ) != KErrNotFound )
 				{
-				WRITELOG1( "CHarvesterVideoPlugin::GetObjectType - mimetype %S. Object type Audio", mime );
+				WRITELOG1( "CHarvesterVideoPlugin::GetRmTypeL - mimetype %S. Object type Audio", mime );
 				aType.Copy( KAudio );
 				}
 			// Set to Video, regardless how badly file is corrupted
@@ -1303,16 +1314,63 @@
 		aType.Copy( KVideo );
 		}
 	
-    if ( iBlacklist && blackListError == KErrNone )
+    if( blackListError == KErrNone )
         {
-        WRITELOG( "CHarvesterVideoPlugin::GetRmTypeL - Removing URI from blacklist" );
-        iBlacklist->RemoveFile( tempName, mediaId );
+        RemoveFileFromBlackList( tempName, mediaId );
         }
     
-	helixMetadata->ResetL();
     CleanupStack::PopAndDestroy( helixMetadata );
 	}
 
+TInt CHarvesterVideoPlugin::AddFileToBlackList( const TFileName& aFullName, const TUint32& aMediaId )
+    {
+    TInt blackListError( KErrNone );
+
+    TTime modified ( 0 );
+    blackListError = iFs.Modified( aFullName, modified );
+    if( blackListError == KErrNone )
+        {
+        WRITELOG( "CHarvesterVideoPlugin::AddFileToBlackList - Adding URI to blacklist" );
+        iBlacklist->AddFile( aFullName, aMediaId, modified );
+        }
+
+    return blackListError;
+    }
+
+TInt CHarvesterVideoPlugin::RemoveFileFromBlackList( const TFileName& aFullName, const TUint32& aMediaId )
+    {
+    TInt blackListError( KErrNone );
+
+    if( iBlacklist )
+        {
+        WRITELOG( "CHarvesterVideoPlugin::RemoveFileFromBlackList - Removing URI from blacklist" );
+        blackListError = iBlacklist->RemoveFile( aFullName, aMediaId );
+        }
+
+    return blackListError;
+    }
+
+TInt CHarvesterVideoPlugin::GetFileFullNameAndMediaId( const RFile64& aFile, TFileName& aFullName, TUint32& aMediaId)
+    {
+    TInt blackListError( KErrNone );
+
+    if( iBlacklist )
+        {
+        WRITELOG( "CHarvesterVideoPlugin::GetFileFullNameAndMediaId" );
+        blackListError = aFile.FullName( aFullName );
+        if( blackListError == KErrNone )
+            {
+            blackListError = iMediaIdUtil->GetMediaId( aFullName, aMediaId );
+            }
+        }
+    else
+        {
+        blackListError = KErrNotReady;
+        }
+ 
+    return blackListError;
+    }
+
 const THarvestingHandling* CHarvesterVideoPlugin::FindHandler( const TDesC& aUri )
 	{
 	TParsePtrC parse( aUri );
--- a/harvester/harvesterplugins/WMVPlugin/data/2000B431.rss	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/harvesterplugins/WMVPlugin/data/2000B431.rss	Wed Jun 09 10:09:20 2010 +0300
@@ -44,7 +44,7 @@
                     version_no          =  1;
                     display_name        =  "Harvester WMV Plugin";
                     default_data        =  "Video";
-                    opaque_data         =  "wm asf";
+                    opaque_data         =  "wm";
                     rom_only = 0;
                     }
                 };
--- a/harvester/monitorplugins/mdsfileserverplugin/src/mdsfileserverplugin.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/monitorplugins/mdsfileserverplugin/src/mdsfileserverplugin.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -189,6 +189,9 @@
 	
 	TInt function = aRequest.Function();
 	
+	iFileName.Zero();
+    iNewFileName.Zero();
+	
 #ifdef _DEBUG_EVENTS
     PrintDebugEvents( function );
 #endif
@@ -557,9 +560,6 @@
             }
         }
     
-    iFileName.Zero();
-    iNewFileName.Zero();
-    
     WRITELOG( "CMdsFileServerPlugin::DoRequestL() - return" );
     return err;
     }
--- a/harvester/server/inc/harvesterao.h	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/server/inc/harvesterao.h	Wed Jun 09 10:09:20 2010 +0300
@@ -522,6 +522,9 @@
         
         /** */
         RPointerArray<CHarvesterData> iContainerPHArray;
+        
+		/** */
+        RPointerArray<CHarvesterData> iTempReadyPHArray;
                 
         /**
          * Pointer to process origin mapper for registering mappings.
@@ -580,6 +583,8 @@
         
         HBufC* iPhoneSoundsPath;
         HBufC* iMmcSoundsPath;
+        
+        TBool iUnmountDetected;
 	};
 	
 #endif //__CHARVESTERAO_H__
--- a/harvester/server/src/harvesterao.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/harvester/server/src/harvesterao.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -143,6 +143,8 @@
     iManualPauseEnabled = EFalse;
     iFastHarvestNeeded = EFalse;
     iHarvestingPlaceholders = EFalse;
+    
+    iUnmountDetected = EFalse;
     }
      
 // ---------------------------------------------------------------------------
@@ -206,6 +208,9 @@
     iContainerPHArray.ResetAndDestroy();
     iContainerPHArray.Close();
     
+    iTempReadyPHArray.ResetAndDestroy();
+    iTempReadyPHArray.Close();
+    
 	delete iHarvesterOomAO;
     delete iRestoreWatcher;
 	delete iOnDemandAO;
@@ -454,6 +459,8 @@
 	{
     WRITELOG1( "CHarvesterAO::HandleUnmount(%d)", aMediaId );    
     
+    iUnmountDetected = ETrue;
+    
     if( !iServerPaused )
         {
         // Stop harvesting for unmount
@@ -560,6 +567,37 @@
 
    removed = 0;
    
+#ifdef _DEBUG
+   WRITELOG1( "CHarvesterAO::HandleUnmount() iTempReadyPHArray.Count() = %d", iTempReadyPHArray.Count() );
+#endif
+   arrayCount = iTempReadyPHArray.Count();
+   if( arrayCount > 0 )
+        {
+        for( TInt i=arrayCount-1; i>= 0; i--)
+            {
+            hd = iTempReadyPHArray[i];
+            err = iMediaIdUtil->GetMediaId( hd->Uri(), mediaId );
+            
+            if( err == KErrNone && mediaId == aMediaId )
+                {
+                WRITELOG1( "CHarvesterAO::HandleUnmount() remove iTempReadyPHArray %d", i);
+                delete hd;
+                hd = NULL;
+                iTempReadyPHArray.Remove( i );
+                removed++;
+                arrayCount--;
+                }
+            }
+        if( iTempReadyPHArray.Count() == 0 )
+            {
+            iTempReadyPHArray.Compress();
+            }
+        WRITELOG1( "CHarvesterAO::HandleUnmount() DecreaseItemCountL iTempReadyPHArray %d", removed);
+        TRAP_IGNORE( iHarvesterEventManager->DecreaseItemCountL( EHEObserverTypePlaceholder, removed) );
+        }
+   
+   removed = 0;
+   
 	const TUint count = iQueue->ItemsInQueue();
 	WRITELOG1( "CHarvesterAO::HandleUnmount() iQueue.Count() = %d", count );
 	if( count > 0 )
@@ -762,6 +800,7 @@
             if ( err != KErrNone )
                 {
                 iPHArray.ResetAndDestroy();
+                iTempReadyPHArray.ResetAndDestroy();
                 User::Leave( err );
                 }
             
@@ -769,6 +808,10 @@
             for( TInt i = 0; i < count; i++ )
                 {
                 CheckFileExtensionAndHarvestL( iReadyPHArray[i] );
+                if( iUnmountDetected )
+                    {
+                    break;
+                    }
                 iReadyPHArray.Remove( i );
                 // correct the index so harvesting order remains ok
                 i--;
@@ -786,6 +829,11 @@
 	    	else
 	    		{
 	    		CheckFileExtensionAndHarvestL( hd );
+	    		if( iUnmountDetected )
+	    		    {
+	    		    iQueue->Append( hd );
+	    		    return;
+	    		    }
 	    		}
     		}
 			
@@ -797,6 +845,7 @@
 	    	if ( err != KErrNone )
 	    		{
 	    		iPHArray.ResetAndDestroy();
+	    		iTempReadyPHArray.ResetAndDestroy();
 	    		User::Leave( err );
 	    		}
     		}
@@ -809,6 +858,10 @@
             }
         iHarvestingPlaceholders = EFalse;
         CheckFileExtensionAndHarvestL( hd );
+        if( iUnmountDetected )
+            {
+            iQueue->Append( hd );
+            }
     	}
     }
 
@@ -845,9 +898,26 @@
 		    iHarvesterPluginFactory->GetObjectDefL( *hd, objDefStr );
 		    }
 		
+		// GetObjectDef can cause context switch, and if unmount happens when this execution is 
+		// interrupted, the ph arrays can be invalid. Thus, abort whole run, and start over to make sure 
+		// the arrays are valid.
+		if( iUnmountDetected )
+		    {
+		    WRITELOG( "CHarvesterAO::HandlePlaceholdersL() - Unmount detected during execution!" );
+		    for( TInt y( iTempReadyPHArray.Count() -1 ); y >=0; y-- )
+		        {
+		        CHarvesterData* hd = iTempReadyPHArray[y];
+		        iPHArray.Insert( hd, 0 );
+		        }
+		    iTempReadyPHArray.Reset();
+		    CleanupStack::PopAndDestroy( &mdeObjectArray );
+		    return;
+		    }
+		
 		if( objDefStr.Length() == 0 ||
 		    ( objDefStr == KInUse ) )
 			{
+		    WRITELOG( "CHarvesterAO::HandlePlaceholdersL() - no objectDef or in use, failing harvesting" );
 			const TInt error( KErrUnknown );
             // notify observer, notification is needed even if file is not supported
             HarvestCompleted( hd->ClientId(), hd->Uri(), error );
@@ -1018,12 +1088,20 @@
 	    
 	    CleanupStack::Pop( mdeObject );
 		
-		iReadyPHArray.Append( hd );
+	    iTempReadyPHArray.Append( hd );
 		iPHArray.Remove( i );
         i--;
         endindex--;
 		}
 	
+	const TInt tempArrayCount( iTempReadyPHArray.Count() );
+	for( TInt i( 0 ); i < tempArrayCount; i++ )
+	    {
+	    CHarvesterData* hd = iTempReadyPHArray[i];
+	    iReadyPHArray.Append( hd );
+	    }
+	iTempReadyPHArray.Reset();
+	
 	const TInt objectCount = mdeObjectArray.Count();  
 	
     if( objectCount > 0 )
@@ -1057,6 +1135,8 @@
 	iPHArray.ResetAndDestroy();
 	
 	CleanupStack::PopAndDestroy( &mdeObjectArray );
+	
+	WRITELOG( "CHarvesterAO::HandlePlaceholdersL() - end" );
 	}
 
 // ---------------------------------------------------------------------------
@@ -1076,6 +1156,14 @@
     	WRITELOG1( "CHarvesterAO::CheckFileExtensionAndHarvestL() - no mdeobject. URI: %S", &uri );
 	    TBuf<KObjectDefStrSize> objDefStr;
 		iHarvesterPluginFactory->GetObjectDefL( *aHD, objDefStr );
+
+        // GetObjectDef can cause context switch, and if unmount happens when this execution is 
+        // interrupted, the ph data can be invalid. Thus, abort whole run, and start over to make sure 
+        // the data is valid.
+        if( iUnmountDetected )
+            {
+            return;
+            }
 		
 		if( objDefStr.Length() == 0 )
 			{
@@ -1506,13 +1594,11 @@
 TInt CHarvesterAO::PauseHarvester()
     {
     WRITELOG( "CHarvesterAO::PauseHarvester()" );
-
-    Cancel();
     
     iHarvesterPluginFactory->PauseHarvester( ETrue );
     iServerPaused = ETrue;
     
-    if( !iRamFull && !iDiskFull )
+    if( !iRamFull && !iDiskFull && !iUnmountDetected )
         {
         iManualPauseEnabled = ETrue;
         }
@@ -1533,9 +1619,14 @@
     
     iHarvesterPluginFactory->PauseHarvester( EFalse );
     iServerPaused = EFalse;
-    iManualPauseEnabled = EFalse;
     
-    SetNextRequest( ERequestHarvest );
+    if( !iManualPauseEnabled &&
+        iNextRequest == ERequestIdle )
+        {
+        SetNextRequest( ERequestHarvest );
+        }
+    
+    iManualPauseEnabled = EFalse;
     }
 
 // ---------------------------------------------------------------------------
@@ -1550,6 +1641,10 @@
     	{
     	iNextRequest = ERequestIdle;
     	}
+    
+    // Reset unmount flag, as unmount is handled before RunL is called again after aborted harvesting run
+    iUnmountDetected = EFalse;
+    
     User::LeaveIfError( iStatus.Int() );
     switch( iNextRequest )
         {
@@ -1560,6 +1655,7 @@
             iReadyPHArray.Compress();
             iContainerPHArray.Compress();
             iPHArray.Compress();
+            iTempReadyPHArray.Compress();
             }
         break;
 
@@ -1571,6 +1667,7 @@
             // harvest new items first...
             if ( iQueue->ItemsInQueue() > 0 )
                 {
+                WRITELOG( "CHarvesterAO::RunL - Items in queue - calling ReadItemFromQueueL()" );
                 ReadItemFromQueueL();
 				SetNextRequest( ERequestHarvest );
 				break;
@@ -1579,10 +1676,12 @@
             // no more items to handle from main queue
             else
                 {
+                WRITELOG( "CHarvesterAO::RunL - No items in main queue" );
                 // All registered fast harvested items or placeholders handled at this point     
                 // if container files to harvest, handle those next
                 if( iContainerPHArray.Count() > 0 )
                 	{
+                    WRITELOG( "CHarvesterAO::RunL - Items in iContainterPHArray - requesting ERequestContainerPlaceholder handling" );
                     iFastHarvestNeeded = EFalse;
                     iHarvestingPlaceholders = EFalse;
                     SetPriority( KHarvesterPriorityHarvestingPlugin );
@@ -1591,6 +1690,9 @@
                 	}
                 else if( iHarvestingPlaceholders || iFastHarvestNeeded )
                     {
+                    WRITELOG( "CHarvesterAO::RunL - No items in iContainerPHArray" );
+                    WRITELOG( "CHarvesterAO::RunL - PlaceholderHarvesting or FastHarvesting were enabled -> reset" );
+                    WRITELOG( "CHarvesterAO::RunL - next request for ERequestHarvest handling" );
                     // reset to default priority       
                     iFastHarvestNeeded = EFalse;
                     iHarvestingPlaceholders = EFalse;
@@ -1599,6 +1701,8 @@
                     break;
                     }
                 
+                WRITELOG( "CHarvesterAO::RunL - starting handling of iReadyPHArray items" );
+                
                 const TInt arrayCount( iReadyPHArray.Count() );
 				if( arrayCount > 0 )
             		{
@@ -1613,6 +1717,10 @@
             		for( TInt i = 0; i < endIndex; i++ )
             			{
                 		CheckFileExtensionAndHarvestL( iReadyPHArray[i] );
+                		if( iUnmountDetected )
+                		    {
+                		    break;
+                		    }
                 		iReadyPHArray.Remove( i );
                         // correct the index so harvesting order remains ok
                         i--;
@@ -1653,6 +1761,7 @@
 	    		{
 	    	    iContainerPHArray.ResetAndDestroy();
 	    		iPHArray.ResetAndDestroy();
+	    		iTempReadyPHArray.ResetAndDestroy();
 	    		User::Leave( err );
 	    		}
 	    	SetNextRequest( ERequestHarvest );
@@ -2421,6 +2530,7 @@
         if( aHD->Origin() == MdeConstants::Object::ECamera )
         	{
             aHD->MdeObject().SetPlaceholder( EFalse );
+            TRAP_IGNORE( iHarvesterEventManager->DecreaseItemCountL( EHEObserverTypePlaceholder ) );
         	TRAPD(mdeError, iMdeObjectHandler->SetMetadataObjectL( *aHD ) );
         	if(mdeError != KErrNone)
             	{
--- a/inc/mdscommoninternal.h	Tue May 25 13:10:05 2010 +0300
+++ b/inc/mdscommoninternal.h	Wed Jun 09 10:09:20 2010 +0300
@@ -35,8 +35,7 @@
 _LIT( KDCIMFolder, ":\\DCIM");
 
 // schema file version
-const TInt KSchemaFileMajorVersion = 2;
-const TInt KSchemaFileMinorVersion = 0;
+const TInt KSchemaFileMajorVersion = 3;
 
 const TDefId KDefaultNamespaceDefId = 1;
 
--- a/metadataengine/client/src/mdeobject.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/metadataengine/client/src/mdeobject.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -122,7 +122,7 @@
 	}
 
 CMdEObject::CMdEObject(CMdESession* aSession, TItemId aId, CMdEObjectDef& aDef)
-		: CMdEInstanceItem( aSession, aId ), iDef( &aDef )
+		: CMdEInstanceItem( aSession, aId ), iDef( &aDef ), iUri( NULL )
 	{
 	}
 
@@ -145,6 +145,7 @@
 		}
 
 	delete iUri;
+	iUri = NULL;
 
 	iPropertyArray.ResetAndDestroy();
 	iPropertyArray.Close();
--- a/metadataengine/data/schema.mde	Tue May 25 13:10:05 2010 +0300
+++ b/metadataengine/data/schema.mde	Wed Jun 09 10:09:20 2010 +0300
@@ -93,7 +93,7 @@
 //
 //
 
-version 2.0
+version 3.0
 
 
 namespace http://sw.nokia.com/MdE 0
--- a/metadataengine/server/inc/mdsmaintenanceengine.h	Tue May 25 13:10:05 2010 +0300
+++ b/metadataengine/server/inc/mdsmaintenanceengine.h	Wed Jun 09 10:09:20 2010 +0300
@@ -139,6 +139,8 @@
         CMdSSqlDbMaintenance* iMaintenance;
 
         TInt iFailedImports;
+        
+        TBool iPrivateSchemaFileInvalid;
     };
     
 #endif // __MDSMAINTENANCEENGINE_H__
--- a/metadataengine/server/src/mdsmaintenanceengine.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/metadataengine/server/src/mdsmaintenanceengine.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -59,7 +59,7 @@
 // Constructor
 // ------------------------------------------------
 //
-CMdSMaintenanceEngine::CMdSMaintenanceEngine()
+CMdSMaintenanceEngine::CMdSMaintenanceEngine() : iPrivateSchemaFileInvalid( EFalse )
     {
     }
 
@@ -129,32 +129,50 @@
     	iMaintenance->CreateDatabaseL( );
 		const TUint KMdSServerUid = 0x0320e65f; // temporal uid
 
-		// try to read schema file from C drive
-		TRAPD( err, ImportSchemaL( aSchema, KSchemaImportFile, KMdSServerUid) );
+		TInt schemaError( KErrNone );
+		
+		if( iPrivateSchemaFileInvalid )
+		    {
+		    // if schema was updated in FOTA update, read the updated schema from ROM
+		    TRAP( schemaError, ImportSchemaL( aSchema, KSchemaRomImportFile, KMdSServerUid) );
+		    }
+		else
+		    {
+		    // try to read schema file from C drive
+		    TRAP( schemaError, ImportSchemaL( aSchema, KSchemaImportFile, KMdSServerUid) );
+		    }
 
-		if( err != KErrNone )
+		if( schemaError != KErrNone )
 			{
-			__LOG1( ELogAlways, "Schema reading error: %d", err );
+			__LOG1( ELogAlways, "Schema reading error: %d", schemaError );
 			// if schema file is not found, try to read from rom (Z) drive
-			if ( err == KErrNotFound || err == KErrPathNotFound )
+			if ( schemaError == KErrNotFound || schemaError == KErrPathNotFound )
 				{
-				TRAP( err, ImportSchemaL( aSchema, KSchemaRomImportFile, KMdSServerUid) );
+				TRAP( schemaError, ImportSchemaL( aSchema, KSchemaRomImportFile, KMdSServerUid) );
 				}
-			if( err != KErrNone )
+			else if( !iPrivateSchemaFileInvalid && schemaError == KErrCorrupt )
+			    {
+			    iPrivateSchemaFileInvalid = ETrue;
+			    }
+			else
+			    {
+			    schemaError = KErrUnknown;
+			    }
+			if( schemaError != KErrNone )
 				{
-				__LOG1( ELogAlways, "Schema reading error: %d", err );
+				__LOG1( ELogAlways, "Schema reading error: %d", schemaError );
 				DeleteDatabase();
-				User::Leave( err );
+				User::Leave( schemaError );
 				}
 			}
 
 		if ( FailedImports() != 0 )
   			{
-	       	User::Leave( KErrCorrupt );
+	       	User::Leave( KErrBadName );
        		}
 		
 		// try to read default import file from C drive
-       	TRAP( err, ImportMetadataL( aManipulate, aSchema, KMdsDefaultImportFile ) );
+       	TRAPD( err, ImportMetadataL( aManipulate, aSchema, KMdsDefaultImportFile ) );
        	if ( err == KErrNotFound || err == KErrPathNotFound )
        		{
        		// if default import file is not found, try to read from rom (Z) drive
--- a/metadataengine/server/src/mdsserver.cpp	Tue May 25 13:10:05 2010 +0300
+++ b/metadataengine/server/src/mdsserver.cpp	Wed Jun 09 10:09:20 2010 +0300
@@ -400,7 +400,46 @@
     iManipulate = CMdSManipulationEngine::NewL( *iSchema, *iNotifier, 
         *iLockList );
 
-    iMaintenance->InstallL( *iManipulate, *iSchema );
+    // TRAP InstallL - first time for if there has been schema update, and 
+    // the DB version is too old. Delete the DB and try to recreate it
+    TRAPD( error, iMaintenance->InstallL( *iManipulate, *iSchema ) );
+    if( error == KErrCorrupt )
+        {
+        delete iSchema;
+        iSchema = NULL; // for CS
+        iSchema = CMdsSchema::NewL();
+        
+        delete iManipulate;
+        iManipulate = NULL; // for CS
+        iManipulate = CMdSManipulationEngine::NewL( *iSchema, *iNotifier, 
+            *iLockList );
+    
+        CMdSMaintenanceEngine::InitConnectionL();    
+        // TRAP InstallL - second time for if the schema file in private not updated
+        // during update, and the first attempt to recreate the DB fails. 
+        // Then schema file in rom is used for final attempt to recreate the DB
+        TRAP( error, iMaintenance->InstallL( *iManipulate, *iSchema ) );
+        if( error == KErrCorrupt )
+            {
+            delete iSchema;
+            iSchema = NULL; // for CS
+            iSchema = CMdsSchema::NewL();
+            
+            delete iManipulate;
+            iManipulate = NULL; // for CS
+            iManipulate = CMdSManipulationEngine::NewL( *iSchema, *iNotifier, 
+                *iLockList );
+        
+            CMdSMaintenanceEngine::InitConnectionL();    
+            // If the DB cannot be created from ANY available schema file, nothing can be 
+            // can be done at this point, unfortunately
+            iMaintenance->InstallL( *iManipulate, *iSchema );
+            }
+        }
+    else if( error != KErrNone )
+        {
+        User::Leave( error );
+        }
     }
 
 void CMdSServer::DeInitializeL()
Binary file sis/mds/mds_stub.sis has changed
--- a/sis/mds/package.pkg	Tue May 25 13:10:05 2010 +0300
+++ b/sis/mds/package.pkg	Wed Jun 09 10:09:20 2010 +0300
@@ -17,7 +17,7 @@
 &EN
 
 ;packet-header (name, uid, major, minor, build, type)
-#{"Metadata System Upgrade"},(0x200009F5), 9, 20, 15, TYPE=SA, RU
+#{"Metadata System Upgrade"},(0x200009F5), 9, 20, 17, TYPE=SA, RU
 
 ; Localised vendor name
 %{"Nokia"}
--- a/sis/mds/package_separate.pkg	Tue May 25 13:10:05 2010 +0300
+++ b/sis/mds/package_separate.pkg	Wed Jun 09 10:09:20 2010 +0300
@@ -17,7 +17,7 @@
 &EN
 
 ;packet-header (name, uid, major, minor, build, type)
-#{"Metadata System Upgrade"},(0x200009F5), 9, 20, 15, TYPE=SA, RU
+#{"Metadata System Upgrade"},(0x200009F5), 9, 20, 17, TYPE=SA, RU
 
 ; Localised vendor name
 %{"Nokia"}
--- a/sis/mds/stub.pkg	Tue May 25 13:10:05 2010 +0300
+++ b/sis/mds/stub.pkg	Wed Jun 09 10:09:20 2010 +0300
@@ -17,7 +17,7 @@
 &EN
 
 ; Header
-#{"Metadata System"}, (0x200009F5), 9, 20, 15, TYPE=SA
+#{"Metadata System"}, (0x200009F5), 9, 20, 17, TYPE=SA
 
 ; Localised Vendor name
 %{"Nokia"}