menucontentsrv/srvsrc/mcsrunningappshandler.cpp
changeset 0 79c6a41cd166
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/menucontentsrv/srvsrc/mcsrunningappshandler.cpp	Thu Dec 17 08:54:17 2009 +0200
@@ -0,0 +1,524 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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 <mcsdef.h>
+#include "mcsmenuitem.h"
+#include "mcsrunningappshandler.h"
+#include "mcsrunningappswgmonitor.h"
+#include "mcsrunningappsfswmonitor.h"
+#include "mcsrunningappshiddenattrscanner.h"
+#include "mcsrunningappsaddremovehandler.h"
+#include "mcsmenunotifier.h"
+#include "mcscachehandler.h"
+
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::NewL
+// ---------------------------------------------------------
+//
+CMcsRunningAppsHandler* CMcsRunningAppsHandler::NewL(
+    CMenuEng& aEng, CMcsCacheHandler& aCacheHandler )
+	{
+	CMcsRunningAppsHandler* self;
+	self = new ( ELeave ) CMcsRunningAppsHandler( aEng, aCacheHandler );
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::~CMcsRunningAppsHandler
+// ---------------------------------------------------------
+//
+CMcsRunningAppsHandler::~CMcsRunningAppsHandler()
+    {
+    delete iWindowGroupMonitor;
+    delete iFswMonitor;
+    delete iHiddenAttrScanner;
+    delete iAddRemoveHandler;
+    iRunningApps.Close();
+    iRunningFolderStatus.Close();
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::CMcsRunningAppsHandler
+// ---------------------------------------------------------
+//
+CMcsRunningAppsHandler::CMcsRunningAppsHandler(
+	CMenuEng& aEng, CMcsCacheHandler& aCacheHandler ):
+	iEng(aEng), 
+	iCacheHandler(aCacheHandler)
+    {
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::ConstructL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::ConstructL()
+	{
+	//iFswMonitor and iHiddenAttrScanner must be initialized before
+	//iWindowGroupMonitor, because they update lists which are used by
+	//iWindowGroupMonitor
+	iFswMonitor = CMcsRunningAppsFswMonitor::NewL( iEng, this );
+    iHiddenAttrScanner = CMcsRunningAppsHiddenAttrScanner::NewL( iEng, this );
+    iWindowGroupMonitor = CMcsRunningAppsWgMonitor::NewL( iEng, this );
+    iAddRemoveHandler = CMcsRunningAppsAddRemoveHandler::NewL( iEng, this );
+    UpdateFoldersRunningStatusL();
+    
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::EngineEventsL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::EngineEventsL( TInt aFolder, TInt aEvents )
+	{
+    if ( aEvents & RMenuNotifier::EItemsAddedRemoved )
+        {
+        iAddRemoveHandler->HandleAddRemoveL( aFolder );
+        iHiddenAttrScanner->ScanL();
+        }    
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::EngineEvents
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::EngineEvents( TInt aFolder, TInt aEvents )
+	{
+	TRAP_IGNORE( EngineEventsL( aFolder, aEvents ) );      
+	}
+
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::EngineEvents
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::GetRunningAppsL( RArray<TUid>& aArray )
+	{
+	for ( TInt i = 0; i< iRunningApps.Count(); i++ )
+		{
+		if ( iRunningApps[i].IsRunning() &&
+				!iRunningApps[i].IsHidden() &&
+				!iRunningApps[i].IsFswHidden() )
+			{
+			aArray.AppendL( iRunningApps[i].GetUid() );
+			}
+		}
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleListUpdateL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleListUpdateL(const RArray<TUid>& aArray, 
+		TArrayDataType aType )
+	{
+	switch ( aType )
+		{
+		case ERunningApps:
+			HandleRunningAppsChangedL( aArray );
+			break;
+		case EFswHiddenApps:
+			HandleFswHiddenAppsChangedL( aArray );
+			break;
+		case EHiddenApps:
+			HandleHiddenAppsChangedL( aArray );
+			break;
+		}
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleRunningAppsChangedL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleRunningAppsChangedL(
+		const RArray<TUid>& aArray )
+	{
+	TInt count = iRunningApps.Count();
+	//add new items to iRunningApps
+	for ( TInt i = 0; i < aArray.Count(); i++ )
+		{
+		TRunningAppsAttr item( aArray[i] );
+		TInt id = iRunningApps.Find( item, TRunningAppsAttr::MatchByUid );
+		if (KErrNotFound == id)
+			{
+			item.SetRunning( ETrue );
+			item.SetFswHidden( iFswMonitor->IsFswHidden( aArray[i] ) );
+			item.SetHidden( iHiddenAttrScanner->IsHidden( aArray[i] ) );
+			iRunningApps.AppendL( item );
+			if ( !item.IsFswHidden() && !item.IsHidden() )
+				{
+				HandleNotificationL( aArray[i] );
+				}
+			}
+		}
+	//set proper running attribute value in iRunningApps 
+	//(only for applications that were previously in Array)
+	for ( TInt i = 0; i< count; i++ )
+		{
+		TUid appUid ( iRunningApps[i].GetUid() );
+		
+		TInt id = aArray.Find( appUid );
+		if ( ( KErrNotFound == id ) && ( iRunningApps[i].IsRunning() ) )
+			{
+			iRunningApps[i].SetRunning( EFalse );
+			if ( !iRunningApps[i].IsFswHidden() && 
+					!iRunningApps[i].IsHidden() )
+				{
+				HandleNotificationL( appUid );
+				}
+			}
+		else if ( ( KErrNotFound != id ) && ( !iRunningApps[i].IsRunning() ) )
+			{
+			iRunningApps[i].SetRunning( ETrue );
+			if ( !iRunningApps[i].IsFswHidden() && 
+					!iRunningApps[i].IsHidden() )
+				{
+				HandleNotificationL( appUid );
+				}
+			}
+		}
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleFswHiddenAppsChangedL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleFswHiddenAppsChangedL(
+		const RArray<TUid>& aArray )
+	{
+	//set proper FSW hidden value in iRunningApps 
+	for ( TInt i = 0; i< iRunningApps.Count(); i++ )
+		{
+		TUid appUid ( iRunningApps[i].GetUid() );
+		TInt id = aArray.Find( appUid );
+		if ( ( KErrNotFound == id ) && ( iRunningApps[i].IsFswHidden() ) )
+			{
+			iRunningApps[i].SetFswHidden( EFalse );
+			if ( iRunningApps[i].IsRunning() && 
+					!iRunningApps[i].IsHidden() )
+				{
+				HandleNotificationL( appUid );
+				}
+			}
+		else if ( ( KErrNotFound != id ) && ( !iRunningApps[i].IsFswHidden() ) )
+			{
+			iRunningApps[i].SetFswHidden( ETrue );
+			if ( iRunningApps[i].IsRunning() && 
+					!iRunningApps[i].IsHidden() )
+				{
+				HandleNotificationL( appUid );
+				}
+			}
+		}	
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleHiddenAppsChangedL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleHiddenAppsChangedL(
+		const RArray<TUid>& aArray )
+	{
+	//set proper hidden value in iRunningApps 
+	for ( TInt i = 0; i< iRunningApps.Count(); i++ )
+		{
+		TUid appUid ( iRunningApps[i].GetUid() );
+		TInt id = aArray.Find( appUid );
+		if ( ( KErrNotFound == id ) && ( iRunningApps[i].IsHidden() ) )
+			{
+			iRunningApps[i].SetHidden( EFalse );
+			if ( iRunningApps[i].IsRunning() && 
+					!iRunningApps[i].IsFswHidden() )
+				{
+				HandleNotificationL( appUid );
+				}
+			}
+		else if ( ( KErrNotFound != id ) && ( !iRunningApps[i].IsHidden() ) )
+			{
+			iRunningApps[i].SetHidden( ETrue );
+			if ( iRunningApps[i].IsRunning() && 
+					!iRunningApps[i].IsFswHidden() )
+				{
+				HandleNotificationL( appUid );
+				}			
+			}
+		}		
+	}
+
+
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleNotificationL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleNotificationL( TInt aId )
+	{
+    TInt root;
+    iEng.RootFolderL( root ); 	
+	TInt parentId(0);                
+	if ( aId != KErrNotFound )
+		{
+		//remove running status from cache (for application)
+		iCacheHandler.HandleRemoveAttribute( aId, KRunningStatus );
+		TBool oldStatus;
+		TBool newStatus;
+	    while( aId != root )
+	    	{
+	        iEng.ParentFolderL( aId, parentId );
+	        iEng.AppendNotifyL(parentId, 
+	        		RMenuNotifier::EItemAttributeChanged);
+	        
+	        oldStatus = GetFolderPreviousRunningStatusL( parentId );
+	        newStatus = GetFolderRunningStatusL( parentId );
+	        if( oldStatus != newStatus )
+				{
+				iCacheHandler.HandleRemoveAttribute( 
+						parentId, KRunningStatus );
+				UpdateFolderRunningStatusL( parentId, newStatus );
+				aId = parentId;
+				}
+	        else
+	        	{
+	        	break;
+	        	}
+	    	}//while
+		}//if
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleNotificationL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleNotificationL( TUid aAppUid )
+	{
+	RArray<TMenuItem> itemArray;
+	CleanupClosePushL( itemArray );
+	//list of all items representing specified uid 
+	TInt error = GetItemsListL( aAppUid, itemArray );
+	if( error == KErrNone )
+		{
+		TInt count = itemArray.Count();
+		for( TInt i = 0; i < count; i++ )
+			{
+			HandleNotificationL( itemArray[i].Id() );
+			}
+		}
+    CleanupStack::PopAndDestroy( &itemArray );
+	}
+
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::GetItemsListL
+// ---------------------------------------------------------
+//
+
+TInt CMcsRunningAppsHandler::GetItemsListL( TUid aAppUid, RArray<TMenuItem>& aItemArray )
+    {
+    TInt result(KErrNotFound);
+    TInt root;
+    iEng.RootFolderL( root );
+    TMenuSrvTypeAttrFilter appFilter;
+    appFilter.SetType( KMenuTypeApp() );
+    TBuf<KUidChars> uidString;
+    TInt appuid( aAppUid.iUid );
+    MenuSrvUtil::UidToStringL( appuid, uidString, EFalse, EHex );
+    appFilter.SetAttr( KMenuAttrUid(), uidString );
+    iEng.GetItemsL( aItemArray, root, &appFilter, ETrue );
+    //if not found in mcs try with UID in decimal format
+    if (!aItemArray.Count())
+        {
+        MenuSrvUtil::UidToStringL( appuid, uidString, EFalse, EDecimal );
+        appFilter.SetAttr( KMenuAttrUid(), uidString );
+        iEng.GetItemsL( aItemArray, root, &appFilter, ETrue );
+        }
+   if ( aItemArray.Count() )
+        {
+        result = KErrNone;
+        }
+    return result;
+    }    
+
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::UpdateFolderRunningStatusL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::UpdateFolderRunningStatusL( TInt aFolderId, 
+		TBool aNewRunningStatus )
+    {
+    TInt id = iRunningFolderStatus.Find( aFolderId );
+    if ( aNewRunningStatus && ( id == KErrNotFound ))
+    	{
+    	iRunningFolderStatus.AppendL( aFolderId );
+    	}
+    if ( !aNewRunningStatus && ( id != KErrNotFound ))
+    	{
+    	iRunningFolderStatus.Remove( id );
+    	}
+    }
+
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::UpdateFoldersRunningStatusL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::UpdateFoldersRunningStatusL(  )
+    {
+    TMenuSrvTypeFilter filter;
+    filter.SetType( KMenuTypeFolder() );
+      
+    TInt root;
+    iEng.RootFolderL( root );
+    
+    RArray<TMenuItem> aItemArray;
+    CleanupClosePushL(aItemArray);
+    iEng.GetItemsL( aItemArray , root, &filter, ETrue );
+    for ( TInt i = 0; i < aItemArray.Count(); i++ )
+    	{
+    	if ( GetFolderRunningStatusL( aItemArray[i].Id() ) )
+    		{
+    		iRunningFolderStatus.AppendL( aItemArray[i].Id() );
+    		}
+    	}
+    CleanupStack::PopAndDestroy( &aItemArray );
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::GetRunningStatusL
+// ---------------------------------------------------------
+//
+TBool CMcsRunningAppsHandler::GetRunningStatusL( TInt aItemId )
+    {
+    const CMenuEngObject& obj = iEng.ObjectL( aItemId );
+    return GetRunningStatusL( obj );
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::GetRunningStatusL
+// ---------------------------------------------------------
+//
+TBool CMcsRunningAppsHandler::GetRunningStatusL( 
+		const CMenuEngObject& aEngObj )
+    {
+    TBool runningApp( EFalse );
+    if ( aEngObj.Type().CompareF( KMenuTypeApp ) == KErrNone )
+        {
+        TUid appUid;
+        TInt errorUid = CMenuSrvEngUtils::GetAppUid( aEngObj, appUid );
+        
+        if( !errorUid )
+            {
+            runningApp = GetAppRunningStatusL( appUid );
+            }
+        }
+    else if( aEngObj.Type().CompareF( KMenuTypeFolder ) == KErrNone )
+        {
+        runningApp = GetFolderRunningStatusL( aEngObj.Id() );
+        }
+    return runningApp;
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::GetFolderPreviousRunningStatusL
+// ---------------------------------------------------------
+//
+TBool CMcsRunningAppsHandler::GetFolderPreviousRunningStatusL( TInt aId )
+	{
+	if( KErrNotFound == iRunningFolderStatus.Find( aId ) )
+		{
+		return EFalse;
+		}
+	else
+		{
+		return ETrue;
+		}
+	
+	}
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::GetFolderRunningStatusL
+// ---------------------------------------------------------
+//
+TBool CMcsRunningAppsHandler::GetFolderRunningStatusL( TInt aId )
+    {
+    TBool running ( EFalse );
+    TMenuSrvTypeFilter filter;
+    filter.SetType( KMenuTypeApp() );
+    
+    RArray<TMenuItem> aItemArray;
+    CleanupClosePushL(aItemArray);
+    iEng.GetItemsL( aItemArray , aId , &filter, ETrue );
+    for( TInt i = 0; i < aItemArray.Count(); i++)
+        {
+        const CMenuEngObject& obj = iEng.ObjectL( aItemArray[i].Id() );
+        TUid appUid;
+        TInt errorUid = CMenuSrvEngUtils::GetAppUid( obj, appUid );
+        
+        if( !errorUid &&  
+                !(obj.Flags() & TMenuItem::EHidden) )
+            {
+            running = GetAppRunningStatusL( appUid  );
+            }
+        if( running )
+            {
+            break;
+            }
+        }
+    CleanupStack::PopAndDestroy( &aItemArray );
+    return running;
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::GetAppRunningStatusL
+// ---------------------------------------------------------
+//
+TBool CMcsRunningAppsHandler::GetAppRunningStatusL( TUid aUid )
+    {
+    TBool running ( EFalse );
+    
+	TRunningAppsAttr item( aUid );
+	TInt id = iRunningApps.Find( item, TRunningAppsAttr::MatchByUid );
+	
+	if( ( id != KErrNotFound ) &&
+			( iRunningApps[id].IsRunning() ) && 
+			( !iRunningApps[id].IsHidden() ) && 
+			( !iRunningApps[id].IsFswHidden() ) )
+		{
+		running = ETrue;
+		}
+    return running;
+    }
+
+// ---------------------------------------------------------
+// CMcsRunningAppsHandler::HandleAddRemoveRunningAppL
+// ---------------------------------------------------------
+//
+void CMcsRunningAppsHandler::HandleAddRemoveRunningAppL( TInt aFolder )
+	{
+	TBool oldStatus = GetFolderPreviousRunningStatusL( aFolder );
+	TBool newStatus = GetFolderRunningStatusL( aFolder );
+	if ( oldStatus != newStatus )
+		{
+		UpdateFolderRunningStatusL( aFolder, newStatus );
+		HandleNotificationL( aFolder );
+		}
+	}
+
+//  End of File