menucontentsrv/srvsrc/mcsrunningappshandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:54:17 +0200
changeset 0 79c6a41cd166
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* 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