menucontentsrv/srvsrc/menusrvappscanner.cpp
branchRCL_3
changeset 114 a5a39a295112
child 118 8baec10861af
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/menucontentsrv/srvsrc/menusrvappscanner.cpp	Wed Sep 01 12:22:09 2010 +0100
@@ -0,0 +1,1245 @@
+/*
+* 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 <mcsmenuutils.h>
+#include <e32property.h>
+#include <widgetregistryclient.h>
+#include "menusrvappscanner.h"
+#include "menusrvmmchistory.h"
+#include "menueng.h"
+#include "menuengobject.h"
+#include "pathinfo.h"
+#include "menulogger.h"
+#include "centralrepository.h"
+#include "mcssathandler.h"
+#include "menusrvengutils.h"
+#include "bautils.h"
+#include "menuutil.h"
+
+_LIT( KMenuOne, "1" );
+_LIT( KMenuAttrMmcId, "mmc_id" );
+_LIT( KMenuMassStorage, "mass_storage" );
+_LIT( KMenuMmcHistoryFname, "mmchistory" );
+
+// ==================== LOCAL FUNCTIONS ====================
+
+/**
+* Identity function to search in an array of TMenuItems.
+* Identity is the ID.
+* @param aLeft Search term.
+* @param aRight Array item.
+* @return ETrue if ID-s match.
+*/
+LOCAL_C TBool IdMatch( const TMenuItem& aLeft, const TMenuItem& aRight )
+    {
+    return aLeft.Id() == aRight.Id();
+    }
+
+// ==================== MEMBER FUNCTIONS ====================
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::NewL
+// ---------------------------------------------------------
+//
+CMenuSrvAppScanner* CMenuSrvAppScanner::NewL(
+        CMenuEng& aEng, CMenuSrvEngUtils& aSrvEngUtils  )
+    {
+    CMenuSrvAppScanner* scanner = new (ELeave) CMenuSrvAppScanner(
+            aEng, aSrvEngUtils );
+    CleanupStack::PushL( scanner );
+    scanner->ConstructL();
+    CleanupStack::Pop( scanner );
+    return scanner;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::~CMenuSrvAppScanner
+// ---------------------------------------------------------
+//
+CMenuSrvAppScanner::~CMenuSrvAppScanner()
+    {
+    Cancel();
+    delete iMcsSatNotifier;
+    delete iNotifier;
+    iEng.DequeueOperation( *this );
+    delete iMmcHistory;
+    iFs.Close();
+
+    if( iCenRepNotifyHandlerHiddenApps )
+        {
+        iCenRepNotifyHandlerHiddenApps->StopListening();
+        }
+    delete iCenRepNotifyHandlerHiddenApps;
+
+    if( iCenRepNotifyHandlerCPHiddenApps )
+        {
+        iCenRepNotifyHandlerCPHiddenApps->StopListening();
+        }
+    delete iCenRepNotifyHandlerCPHiddenApps;
+
+    if( iCenRepNotifyHandlerCPHiddenFolders )
+        {
+        iCenRepNotifyHandlerCPHiddenFolders->StopListening();
+        }
+    delete iCenRepNotifyHandlerCPHiddenFolders;
+  	delete iCenRepSession;
+  	delete iFreeSpaceObserver;
+
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::CMenuSrvAppScanner
+// ---------------------------------------------------------
+//
+CMenuSrvAppScanner::CMenuSrvAppScanner(
+        CMenuEng& aEng, CMenuSrvEngUtils& aSrvEngUtils )
+: CActive( CActive::EPriorityStandard ), iEng( aEng ),
+  iSrvEngUtils( aSrvEngUtils )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::ConstructL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::ConstructL()
+    {
+    iOpStatus = EFalse;
+    User::LeaveIfError( iFs.Connect() );
+    TFileName path;
+    User::LeaveIfError( iFs.PrivatePath( path ) );
+    TUint attribute;
+    if( iFs.Att( path, attribute) == KErrNotFound )
+    	{
+        TInt mdRes = iFs.MkDirAll( path );
+        if ( mdRes != KErrNone )
+        	{
+        	User::Leave( mdRes );
+        	}
+    	}
+
+    iMmcHistory = new (ELeave) CMenuSrvMmcHistory();
+    iMmcHistory->LoadL( iFs, KMenuMmcHistoryFname() );
+    // The notifier has its own session to apparc, instead of taking
+    // it as argument... :(
+    iNotifier = CApaAppListNotifier::NewL( this, CActive::EPriorityStandard );
+
+   	iCenRepSession = CRepository::NewL( KCRUidMenu );
+
+	iCenRepNotifyHandlerHiddenApps = CCenRepNotifyHandler::NewL(
+	    *this, *iCenRepSession,
+		CCenRepNotifyHandler::EStringKey, KMenuHideApplication );
+	iCenRepNotifyHandlerCPHiddenApps = CCenRepNotifyHandler::NewL(
+	    *this, *iCenRepSession,
+		CCenRepNotifyHandler::EStringKey, KMenuHideCPApplication );
+
+	iCenRepNotifyHandlerCPHiddenFolders = CCenRepNotifyHandler::NewL(
+	    *this, *iCenRepSession,
+		CCenRepNotifyHandler::EStringKey, KMenuHideCPFolder );
+
+	iCenRepNotifyHandlerHiddenApps->StartListeningL();
+	iCenRepNotifyHandlerCPHiddenApps->StartListeningL();
+	iCenRepNotifyHandlerCPHiddenFolders->StartListeningL();
+
+	iMcsSatNotifier = CMcsSatNotifier::NewL(
+	                this, KCRUidMenu, KMenuShowSatUI );
+
+	iFreeSpaceObserver = CMcsFreeSpaceObserver::NewL( *this );
+
+    //SetActive();
+	ScheduleScan();
+    //iOpStatus = ETrue;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::RunL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::RunL()
+    {
+    User::LeaveIfError( iStatus.Int() ); // Handle errors in RunL.
+    // AppArc app scan complete, we have the app list.
+    // Now queue this operation to be executed by the Engine.
+    if ( !MenuUtil::BackupInProgressL() )
+        {
+        iEng.QueueOperationL( *this );
+        }
+    else
+        {
+        iOpStatus = EFalse;
+        }
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::DoCancel
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::DoCancel()
+    {
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::RunError
+// ---------------------------------------------------------
+//
+TInt CMenuSrvAppScanner::RunError( TInt /*aError*/ )
+    {
+    // Ignore the error (what else could we do?).
+    // When next AppArc update occurs, we will run again.
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::UpdateApplicationWithHideIfInstalledItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::UpdateApplicationWithHideIfInstalledItemsL()
+    {
+    TInt root;
+    iEng.RootFolderL( root );
+
+    TMenuSrvAttrExistsFilter appFilter;
+    appFilter.SetAttr( KMenuAttrHideIfInstalledUid() );
+
+    RArray<TMenuItem> items;
+    CleanupClosePushL( items );
+    iEng.GetItemsL( items, root, &appFilter, ETrue );
+
+    for (TInt i=0; i < items.Count(); i++)
+        {
+        TBool wasHidden;
+        TPtrC uidTmp;
+
+        GetHiddenFlagAndUidL( items[i].Id(), wasHidden, uidTmp );
+
+        HideItemIfPresentL( root, items[i].Id(), uidTmp, wasHidden );
+        }
+    CleanupStack::PopAndDestroy( &items );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::GetHiddenFlagAndUidL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::GetHiddenFlagAndUidL( TInt aId, TBool& aHidden, TPtrC& aUidStr )
+    {
+    const CMenuEngObject& object = iEng.ObjectL( aId );
+    aHidden = (0 != (object.Flags() & TMenuItem::EHidden));
+
+    TBool tmp;
+    object.FindAttribute( KMenuAttrHideIfInstalledUid(), aUidStr, tmp);
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HideAppIfExists
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HideItemIfPresentL( TInt aFolder, TInt aId, const TDesC& aUid, TBool aWasHidden )
+    {
+    TBool hideItem = EFalse;
+    TMenuSrvAttrFilter uidAppFilter;
+    uidAppFilter.SetAttr( KMenuAttrUid(), aUid );
+
+    RArray<TMenuItem> appItems;
+    CleanupClosePushL( appItems );
+    iEng.GetItemsL( appItems, aFolder, &uidAppFilter, ETrue );
+
+    for (TInt i=0; i < appItems.Count(); i++)
+        {
+        if(appItems[i].Type() != KMenuTypeLink())
+        	{
+            const TMenuItem& item = appItems[i];
+
+            TBool itemHidden = (0 != (item.Flags() & TMenuItem::EHidden));
+            TBool itemMissing = (0 != (item.Flags() & TMenuItem::EMissing));
+            if ( !itemHidden && !itemMissing )
+                {
+                hideItem = ETrue;
+                }
+        	}
+        }
+
+    SetHiddenFlagL( aId, aWasHidden, hideItem );
+
+    CleanupStack::PopAndDestroy( &appItems );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::SetHiddenFlagL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::SetHiddenFlagL( TInt aId, TBool aWasHidden, TBool aHide )
+    {
+    if ( aWasHidden ^ aHide )
+        {
+        iEng.ModifiableObjectL( aId, RMenuNotifier::EItemsAddedRemoved ).
+            SetFlags( TMenuItem::EHidden, aHide );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::ValidateLinkUidL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::ValidateLinkUidL( TInt aFolder, TInt aId, const TDesC& aUidStr )
+    {
+    TMenuSrvAttrFilter uidAppFilter;
+    uidAppFilter.SetAttr( KMenuAttrUid(), aUidStr );
+
+    RArray<TMenuItem> appItems;
+    CleanupClosePushL( appItems );
+    iEng.GetItemsL( appItems, aFolder, &uidAppFilter, ETrue );
+
+    TBool showItem = EFalse;
+    TBool exists = EFalse;
+    TBool itemMissing = EFalse;
+    for (TInt i=0; i < appItems.Count(); i++)
+        {
+        if(appItems[i].Id() != aId)
+        	{
+            exists = ETrue;
+            const TMenuItem& item = appItems[i];
+
+            TBool itemHidden = (0 != (item.Flags() & TMenuItem::EHidden));
+            itemMissing = (0 != (item.Flags() & TMenuItem::EMissing));
+            if ( !itemHidden && !itemMissing )
+                {
+                showItem = ETrue;
+                }
+        	}
+        }
+
+    UpdateLinkL( aId, exists, showItem, itemMissing );
+
+    CleanupStack::PopAndDestroy( &appItems );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::UpdateLinkL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::UpdateLinkL(
+    TInt aId,
+    TBool aExists,
+    TBool aShowItem,
+    TBool aMissingItem )
+    {
+    if (!aExists)
+        {
+        iEng.ModifiableObjectL( aId ).SetFlags( TMenuItem::ELockDelete, EFalse );
+        iEng.RemoveL( aId );
+        }
+    else if ( !aMissingItem )
+        {
+        const CMenuEngObject& object = iEng.ObjectL( aId );
+        TBool itemHidden = (0 != (object.Flags() & TMenuItem::EHidden));
+        TBool itemMissing = (0 != (object.Flags() & TMenuItem::EMissing));
+        if ( itemHidden == aShowItem )
+            {
+            iEng.ModifiableObjectL( aId, RMenuNotifier::EItemsAddedRemoved  ).
+            SetFlags( TMenuItem::EHidden, !aShowItem );
+            }
+        if ( itemMissing != aMissingItem )
+            {
+            iEng.ModifiableObjectL( aId, RMenuNotifier::EItemsAddedRemoved  ).
+            SetFlags( TMenuItem::EMissing, aMissingItem );
+            }
+        }
+    else
+        {
+        const CMenuEngObject& object = iEng.ObjectL( aId );
+        TBool itemMissing = (0 != (object.Flags() & TMenuItem::EMissing));
+        if ( itemMissing != aMissingItem )
+            {
+            iEng.ModifiableObjectL( aId, RMenuNotifier::EItemsAddedRemoved  ).
+            SetFlags( TMenuItem::EMissing, aMissingItem );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::ValidateLinkRefIdL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::ValidateLinkRefIdL( TInt aId, const TDesC& refIdStr )
+    {
+    TUint refItemId;
+    MenuUtils::GetTUint( refIdStr, refItemId );
+
+    TMenuItem refItem;
+
+    TBool showItem = EFalse;
+    TBool exists = EFalse;
+
+    TRAPD( err, iEng.GetItemL( refItemId, refItem ) );
+
+    if (err == KErrNone)
+        {
+        exists = ETrue;
+        }
+
+    TBool itemHidden = (0 != (refItem.Flags() & TMenuItem::EHidden));
+    TBool itemMissing = (0 != (refItem.Flags() & TMenuItem::EMissing));
+    if ( !itemHidden  && !itemMissing )
+        {
+        showItem = ETrue;
+        }
+
+    UpdateLinkL( aId, exists, showItem, itemMissing );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::ValidateLinkL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::ValidateLinkL( TInt aFolder, TInt aId )
+    {
+    const CMenuEngObject& object = iEng.ObjectL( aId );
+
+    TBool tmp;
+    TPtrC refIdStr;
+    TPtrC uidStr;
+    if ( object.FindAttribute( KMenuAttrRefId(), refIdStr, tmp) )
+        {
+        ValidateLinkRefIdL( aId, refIdStr );
+        }
+    else if ( object.FindAttribute( KMenuAttrUid(), uidStr, tmp) )
+        {
+        ValidateLinkUidL( aFolder, aId, uidStr );
+        }
+    else
+        {
+        UpdateLinkL( aId, EFalse, EFalse, EFalse );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::UpdateLinkItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::UpdateLinkItemsL()
+    {
+    TInt root;
+    iEng.RootFolderL( root );
+
+    TMenuSrvTypeFilter linkFilter;
+    linkFilter.SetType( KMenuTypeLink() );
+
+    RArray<TMenuItem> items;
+    CleanupClosePushL( items );
+    iEng.GetItemsL( items, root, &linkFilter, ETrue );
+
+    for (TInt i=0; i < items.Count(); i++)
+        {
+        ValidateLinkL( root, items[i].Id() );
+        }
+    CleanupStack::PopAndDestroy( &items );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleFreeSpaceEventL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleFreeSpaceEventL()
+    {
+    if ( !IsActive() && !iOpStatus )
+        {
+        iOpStatus = ETrue;
+        TRequestStatus* ownStatus = &iStatus;
+        *ownStatus = KRequestPending;
+        SetActive();
+        User::RequestComplete( ownStatus, KErrNone );
+        }
+    }
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::RunMenuEngOperationL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::RunMenuEngOperationL()
+    {
+    UpdateApplicationItemsL();
+    UpdateApplicationWithHideIfInstalledItemsL();
+    UpdateLinkItemsL();
+    iOpStatus = EFalse;
+    }
+
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::UpdateApplicationItemL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::UpdateApplicationItemL(
+		RArray<TMenuItem>& aMcsItems, const CMenuSrvAppAttributes& aApaItem,
+		TUint aMmcId, TBool isLegacy)
+    {
+    RArray<TMenuItem> mcsUidItems;
+    CleanupClosePushL( mcsUidItems );
+    TUid appuid = aApaItem.GetUid();
+    GetMcsAppItemsL( isLegacy, appuid.iUid, mcsUidItems );
+    TBool isApaItemHidden( aApaItem.IsHidden() );
+
+    // This app is not in the menu, add it now.
+    // We don't add hidden items, there are too many of them!
+    // do not display Menu app
+    if ( !mcsUidItems.Count()
+    		&& !isApaItemHidden
+    		&& appuid !=  KMmUid3  )
+        {
+        if( appuid == KSatUid )
+            {
+            if( CMcsSatHandler::CheckVisibility() )
+             	{
+              	AddAppItemL( aApaItem, aMmcId );
+               	}
+            }
+        else
+          	{
+          	AddAppItemL( aApaItem, aMmcId );
+            GetMcsAppItemsL( isLegacy, appuid.iUid, mcsUidItems );
+           	}
+        }//if
+
+    // if there are any items with legacy UID format
+    // update them to new uid format
+    else if ( mcsUidItems.Count() && isLegacy )
+        {
+        //for every item with matching UID
+        for (TInt j=0; j < mcsUidItems.Count(); j++)
+     		{
+       		CMenuEngObject& object =
+      		                iEng.ModifiableObjectL( mcsUidItems[j].Id() );
+            TBuf<KUidChars> uidString;
+            MenuSrvUtil::UidToStringL( appuid.iUid, uidString, EFalse, EHex );
+       	    object.SetAttributeL( KMenuAttrUid(), uidString, EFalse );
+       		}//for
+        }//else if
+    // "hidden", "missing" and "lock_delete"  flags update
+    for ( TInt j = 0; j < mcsUidItems.Count(); j++ )
+        {
+        const TMenuItem& item = mcsUidItems[j];
+
+        //we need to handle first run of appscanner,
+        //there might be some incorrect data in content xml file
+        //if this will have impact on performance we may run this methods only at start up
+       	HandleMmcAttrUpdateL( item, aApaItem, aMmcId );
+		HandleNativeAttrUpdateL( item, aApaItem );
+
+        // "hidden" flag handling.
+        HandleHiddenFlagUpdateL( item, aApaItem );
+
+        // "missing" flag handling
+        HandleMissingFlagUpdateL( item );
+
+        //"lock_delete" flag handling
+        HandleLockDeleteFlagUpdateL(item, aApaItem );
+        // if item was just added to MCS  it is not present in aMcsItems
+        // so we cannot remove it
+        TInt index = aMcsItems.Find( item, TIdentityRelation<TMenuItem>( IdMatch ) );
+        if ( index != KErrNotFound )
+        	{
+        	aMcsItems.Remove( index );
+        	}
+        }//for
+    CleanupStack::PopAndDestroy( &mcsUidItems );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleHiddenFlagUpdateL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleHiddenFlagUpdateL( const TMenuItem & aItem,
+        const CMenuSrvAppAttributes& aApaItem )
+	{
+	TBool itemHidden = (0 != (aItem.Flags() & TMenuItem::EHidden));
+	if ( aApaItem.GetUid() == KSatUid )
+		{
+		if (itemHidden == CMcsSatHandler::CheckVisibility())
+			{
+			iEng.ModifiableObjectL(aItem.Id(), RMenuNotifier::EItemsAddedRemoved).
+				SetFlags( TMenuItem::EHidden, !CMcsSatHandler::CheckVisibility());
+			}
+		}
+	else if ( itemHidden != aApaItem.IsHidden() )
+		{
+		iEng.ModifiableObjectL(aItem.Id(), RMenuNotifier::EItemsAddedRemoved).
+			SetFlags( TMenuItem::EHidden, aApaItem.IsHidden() );
+		}
+	}
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleNativeAttrUpdateL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleNativeAttrUpdateL(
+		const TMenuItem& aItem, const CMenuSrvAppAttributes& aApaItem )
+	{
+    //we need this to delete uninstalled java app item
+    if( aApaItem.GetAppType() != iEng.ObjectL( aItem.Id() ).GetAppType() )
+    	{
+    	iEng.ModifiableObjectL( aItem.Id(),
+    			RMenuNotifier::EItemsNone ).SetAppType( aApaItem.GetAppType() );
+    	}
+	}
+
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleMmcAttrUpdateL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleMmcAttrUpdateL(
+		const TMenuItem& aItem, const CMenuSrvAppAttributes& aApaItem, TUint aMmcId )
+	{
+    if ( IsInMmc( aApaItem ) )
+    	{
+    	//app is instaled on mmc - KMenuAttrMmcId attribute update
+    	TBuf<KUidChars> uidString;
+        uidString.Format( KHexFormat, aMmcId );
+        iEng.ModifiableObjectL( aItem.Id(), RMenuNotifier::EItemsAddedRemoved ).
+			SetAttributeL( KMenuAttrMmcId, uidString, EFalse );
+    	}
+    else if ( IsInMassStorage( aApaItem )
+    		&& aApaItem.GetAppType() == CMenuEngObject::EWidgetApp )
+    	{
+    	//its java app installed on mass storage, we need to leave it in xml
+    	//in case of connecting usb in mass storage mode
+        iEng.ModifiableObjectL( aItem.Id(), RMenuNotifier::EItemsAddedRemoved ).
+			SetAttributeL( KMenuAttrMmcId, KMenuMassStorage, EFalse );
+    	}
+    else
+    	{
+    	//its installed on c: drive - remove attribute
+		iEng.ModifiableObjectL( aItem.Id(), RMenuNotifier::EItemsAddedRemoved ).
+			RemoveAttribute( KMenuAttrMmcId );
+    	}
+	}
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::UpdateApplicationItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::UpdateApplicationItemsL()
+    {
+    TUint currentMmcId = UpdateMmcHistoryL();
+    // get all MCS items
+    RArray<TMenuItem> mcsItems;
+    CleanupClosePushL( mcsItems );
+    GetMcsAppItemsL( mcsItems );
+    iSrvEngUtils.ReloadApaItemsL();
+    GetCrItemsL( iSrvEngUtils.GetAppItemsL() );
+    TBool isLegacy = iEng.GetOnceLegacyFormat();
+
+
+    //for every item in apaAndCrItems array
+    for ( TInt i = ( iSrvEngUtils.GetAppItemsL().Count() - 1 ); i >= 0 ; i-- )
+        {
+        // if there was leave for any item we ignore it
+        // and proceed to the next one
+        TRAP_IGNORE(UpdateApplicationItemL(
+        		mcsItems, *iSrvEngUtils.GetAppItemsL()[i], currentMmcId, isLegacy));
+        }
+    // Here the big list contains menu items that refer to missing apps.
+    HandleMissingItemsL( mcsItems );
+    CleanupStack::PopAndDestroy( &mcsItems );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleLockDeleteFlagUpdateL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleLockDeleteFlagUpdateL(
+		const TMenuItem& aItem, const CMenuSrvAppAttributes& aApaItem )
+	{
+	TBool isHidden = ( ( iEng.ObjectL( aItem.Id() )
+							.Flags() & TMenuItem::EHidden ) != 0 );
+	if ( !isHidden && IsInRomL( aApaItem ) )
+		{
+		if ( ( aItem.Flags() & TMenuItem::ELockDelete ) == 0 )
+			{
+			iEng.ModifiableObjectL(aItem.Id())
+					.SetFlags( TMenuItem::ELockDelete, ETrue );
+			}
+		}
+	else
+		{
+		if ( ( aItem.Flags() & TMenuItem::ELockDelete ) != 0 )
+			{
+			iEng.ModifiableObjectL(aItem.Id())
+					.SetFlags( TMenuItem::ELockDelete, EFalse );
+			}
+		}
+	}
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleMissingFlagUpdateL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleMissingFlagUpdateL( const TMenuItem& aItem )
+	{
+	if ( aItem.Flags() & TMenuItem::EMissing )
+        {
+        CLOG_WRITE_FORMAT8( "Unsetting flag EMissing on %d", item.Id() );
+        //application found so we unset "missing" flag
+        iEng.ModifiableObjectL( aItem.Id(), RMenuNotifier::EItemsAddedRemoved ).
+            SetFlags( TMenuItem::EMissing, EFalse );
+        }
+	}
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::GetCrItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::GetCrItemsL( RPointerArray<CMenuSrvAppAttributes>& aArray )
+    {
+ 	TBuf<KCenRepBufferSize> buf;
+	iCenRepSession->Get( KMenuHideCPApplication, buf );
+	ParseUidsL( buf, aArray );// parses UIDs from buf and appends them to array
+	iCenRepSession->Get( KMenuHideApplication, buf );
+	ParseUidsL( buf, aArray );// parses UIDs from buf and appends them to array
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::ParseUidsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::ParseUidsL( const TDesC& aHiddenApplications,
+                                        RPointerArray<CMenuSrvAppAttributes>& aArray )
+    {
+    TLex input( aHiddenApplications );
+    TLexMark startMark;
+    input.Mark( startMark );
+    TBool notEmpty = EFalse;
+    while ( !input.Eos() )
+        {
+        if( input.Peek() == ',')
+            {
+            SetHidden(input.MarkedToken( startMark ), aArray);
+            input.Inc();
+            input.Mark( startMark );
+            }
+        input.Inc();
+        notEmpty = ETrue;
+        }
+	if ( notEmpty )
+		{
+		SetHidden(input.MarkedToken( startMark ), aArray);
+		}
+
+
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::SetHidden
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::SetHidden(
+        const TDesC& aHiddenAppUid, RPointerArray<CMenuSrvAppAttributes>& aArray )
+    {
+    TLex appUidDescriptor(aHiddenAppUid);
+    TUint hiddenAppUid( 0 );
+    appUidDescriptor.Val( hiddenAppUid, EHex );
+    if ( hiddenAppUid )
+        {
+        TApaAppCapabilityBuf capability;
+        TApaAppInfo appInfo;
+        appInfo.iUid = TUid::Uid( hiddenAppUid );
+        CMenuSrvAppAttributes* attribute = CMenuSrvAppAttributes::NewLC( capability, appInfo );
+        TInt index = aArray.Find( attribute,
+                TIdentityRelation<CMenuSrvAppAttributes>( CMenuSrvAppAttributes::MatchItems ) );
+        if( index >= 0 && !aArray[index]->IsHidden() )
+            {
+            aArray[index]->SetHidden( ETrue );
+            }
+        CleanupStack::PopAndDestroy( attribute );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::GetMcsItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::GetMcsAppItemsL( RArray<TMenuItem>& aArray )
+    {
+    TInt root;
+    iEng.RootFolderL( root );
+    TMenuSrvTypeFilter appFilter;
+    appFilter.SetType( KMenuTypeApp() );
+    iEng.GetItemsL( aArray, root, &appFilter, ETrue );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::GetMcsItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::GetMcsAppItemsL( TBool aLegacy,
+                       const TUint aUid, RArray<TMenuItem>& aArray )
+    {
+    TInt root;
+    iEng.RootFolderL( root );
+    TMenuSrvTypeAttrFilter appFilter;
+    appFilter.SetType( KMenuTypeApp() );
+    TBuf<KUidChars> uidString;
+    MenuSrvUtil::UidToStringL( aUid, uidString, aLegacy, EHex );
+    appFilter.SetAttr( KMenuAttrUid(), uidString );
+    iEng.GetItemsL( aArray, root, &appFilter, ETrue );
+    //if not found in mcs try with UID in decimal format
+    if (!aArray.Count())
+        {
+        MenuSrvUtil::UidToStringL( aUid, uidString, aLegacy, EDecimal );
+        appFilter.SetAttr( KMenuAttrUid(), uidString );
+        iEng.GetItemsL( aArray, root, &appFilter, ETrue );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::CompletedMenuEngOperation
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::CompletedMenuEngOperation( TInt /*aErr*/ )
+    {
+    iOpStatus = EFalse;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleAppListEvent
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleAppListEvent( TInt /*aEvent*/ )
+    {
+    // We only have one event, EAppListChanged.
+    // Call back RunL async, to requeue and initiate rescan.
+    if ( !IsActive()  && !iOpStatus)
+        {
+        iOpStatus = ETrue;
+        TRequestStatus* ownStatus = &iStatus;
+        *ownStatus = KRequestPending;
+        SetActive();
+        User::RequestComplete( ownStatus, KErrNone );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMenuSrvAppScanner::HandleNotifyString
+// -----------------------------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleNotifyString( TUint32 aKey,
+        const TDesC16& /*aNewValue*/ )
+    {
+    if((aKey == KMenuHideApplication )||(aKey == KMenuHideCPApplication))
+        {
+        if ( !IsActive() && !iOpStatus )
+            {
+            iOpStatus = ETrue;
+            TRequestStatus* ownStatus = &iStatus;
+            *ownStatus = KRequestPending;
+            SetActive();
+            User::RequestComplete( ownStatus, KErrNone );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMenuSrvAppScanner::SATChangeL
+// -----------------------------------------------------------------------------
+//
+void CMenuSrvAppScanner::SATChangeL()
+    {
+    ScheduleScan();
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::ScheduleScan
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::ScheduleScan()
+	{
+	if ( !IsActive() && !iOpStatus )
+		{
+		iOpStatus = ETrue;
+		TRequestStatus* ownStatus = &iStatus;
+		*ownStatus = KRequestPending;
+		SetActive();
+		User::RequestComplete( ownStatus, KErrNone );
+		}
+	}
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::CreateInstallFolderL
+// ---------------------------------------------------------
+//
+TInt CMenuSrvAppScanner::CreateInstallFolderL( const CMenuSrvAppAttributes& aApaItem )
+	{
+    // Find a folder for this app.
+    TInt folder(0);
+    if ( aApaItem.GetGroupName().Length() )
+        {
+        // appgroup_name is defined for this app. Find or create folder.
+        AppGroupFolderL( aApaItem.GetGroupName(), folder );
+        }
+    else
+        {
+        // No appgroup_name, use default folder, if any.
+        DefaultFolderL( folder );
+        }
+    if ( !folder )
+        {
+        // Last resort: it goes to the root.
+        iEng.RootFolderL( folder );
+        }
+    return folder;
+	}
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::AddAppItemL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::AddAppItemL(
+        const CMenuSrvAppAttributes& aApaItem,
+        TUint aCurrentMmcId )
+    {
+    TInt folder = CreateInstallFolderL( aApaItem );
+    // Now add the app item.
+    CMenuEngObject* object = iEng.NewObjectL( KMenuTypeApp() );
+    CleanupStack::PushL( object );
+    TBuf<KUidChars> uidString;
+    _LIT(KHexFormat, "0x%X");
+    uidString.Format( KHexFormat, aApaItem.GetUid().iUid );
+
+    object->SetAttributeL( KMenuAttrUid(), uidString, EFalse );
+    if ( aCurrentMmcId && IsInMmc( aApaItem ) )
+        {
+        // This app is on the MMC, set the "mmc_id" attribute.
+        uidString.Format( KHexFormat, aCurrentMmcId );
+        object->SetAttributeL( KMenuAttrMmcId, uidString, EFalse );
+        }
+    if( aApaItem.GetAppType() == CMenuEngObject::EWidgetApp )
+    	{
+    	//we need this to delete uninstalled java or wrt widget app item
+    	if ( !IsInMmc( aApaItem )
+    			&& IsInMassStorage( aApaItem ) )
+    		{
+    		object->SetAttributeL( KMenuAttrMmcId, KMenuMassStorage, EFalse );
+    		}
+    	}
+    object->SetAppType( aApaItem.GetAppType() );
+    EnsureFolderWritableL( folder );
+    iEng.AddL( *object, folder, 0 );
+    CleanupStack::Pop( object );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::AppGroupFolderL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::AppGroupFolderL( const TDesC& aAppGroupName, TInt& aFolderId )
+    {
+    __ASSERT_DEBUG( aAppGroupName.Length(), User::Invariant() );
+
+    TInt folder = 0;
+    TInt defaultFolderId( 0 );
+    iEng.RootFolderL( defaultFolderId );
+    const CMenuEngObject& rootObject = iEng.ObjectL( defaultFolderId );
+    TPtrC groupName;
+    TBool localized;
+
+    if ( rootObject.FindAttribute( KMenuAttrAppGroupName, groupName, localized ) &&
+    	groupName.Compare( aAppGroupName )==0 )
+        {
+        folder = defaultFolderId;
+        }
+    else
+    	{
+        TMenuSrvTypeAttrFilter filter;
+        filter.SetType( KMenuTypeFolder() );
+        filter.SetAttr( KMenuAttrAppGroupName(), aAppGroupName );
+        RArray<TMenuItem> items;
+        CleanupClosePushL( items );
+
+        iEng.GetItemsL( items, defaultFolderId, &filter, ETrue );
+        if ( items.Count() )
+            {
+            folder = items[0].Id();
+            }
+        CleanupStack::PopAndDestroy( &items );
+    	}
+    if ( !folder )
+        {
+        // No such folder, create it now.
+        CMenuEngObject* object = iEng.NewObjectL( KMenuTypeFolder() );
+        CleanupStack::PushL( object );
+        object->SetAttributeL
+            ( KMenuAttrAppGroupName(), aAppGroupName, EFalse );
+        EnsureFolderWritableL( defaultFolderId );
+        iEng.AddL( *object, defaultFolderId, 0 );
+
+        CleanupStack::Pop( object );
+        folder = object->Id();
+        }
+    __ASSERT_DEBUG( folder, User::Invariant() );
+    aFolderId = folder;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::DefaultFolderL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::DefaultFolderL( TInt& aFolderId )
+    {
+    TInt folder = 0;
+    TMenuSrvTypeAttrFilter filter;
+    filter.SetType( KMenuTypeFolder() );
+    filter.SetAttr( KMenuAttrDefault(), KMenuOne() );
+    RArray<TMenuItem> items;
+    CleanupClosePushL( items );
+    TInt rootId;
+    iEng.RootFolderL( rootId );
+    iEng.GetItemsL( items, rootId, &filter, ETrue );
+    if ( items.Count() )
+        {
+        folder = items[0].Id();
+        }
+    CleanupStack::PopAndDestroy( &items );
+    aFolderId = folder;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::EnsureFolderWritableL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::EnsureFolderWritableL( TInt aFolder )
+    {
+    // This folder should not be read-only! Remove the protection.
+    // Otherwise we can't add the items to it.
+    if ( iEng.ObjectL( aFolder ).Flags() & TMenuItem::ELockMoveInto )
+        {
+        iEng.ModifiableObjectL( aFolder ).
+            SetFlags( TMenuItem::ELockMoveInto, EFalse );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleMissingItemsL
+// ---------------------------------------------------------
+//
+TMenuItem::TFlags CMenuSrvAppScanner::GetProperFlagL( const TMenuItem& aItem )
+    {
+    TMenuItem::TFlags flags = TMenuItem::ENoFlag;
+
+    TUint mmcId = 0;
+    TPtrC val;
+    TBool dummy;
+    if( iEng.ObjectL( aItem.Id() ).FindAttribute( KMenuAttrMmcId(), val, dummy ) )
+        {
+        MenuUtils::GetTUint( val, mmcId );
+        if ( mmcId && KErrNotFound != iMmcHistory->Find( mmcId ) )
+            {
+            // This item is on an MMC which is currently in the MMC history.
+            // Set it "missing" but keep it.
+            flags = TMenuItem::EMissing;
+            }
+        else if ( val == KMenuMassStorage()
+                    && IsDriveInUse( DriveInfo::EDefaultMassStorage ) )
+            {
+            flags = TMenuItem::EMissing;
+            }
+        else if ( iEng.ObjectL( aItem.Id() ).FindAttribute(
+                KMenuAttrPredefined(), val, dummy ) )
+            {
+            flags = TMenuItem::EMissing;
+            }
+        }
+    else if( iEng.ObjectL( aItem.Id() ).GetAppType()
+                != CMenuEngObject::EWidgetApp
+            || iEng.ObjectL( aItem.Id() ).FindAttribute(
+            		KMenuAttrPredefined(), val, dummy ) )
+        {
+        flags = TMenuItem::EHidden;
+        }
+    return flags;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::HandleMissingItemsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::HandleMissingItemsL(
+        const RArray<TMenuItem>& aItems )
+    {
+    for ( TInt i = 0; i < aItems.Count(); i++ )
+        {
+        TMenuItem::TFlags flags = GetProperFlagL( aItems[i] );
+        if( flags == TMenuItem::ENoFlag )
+            {
+            iEng.RemoveL( aItems[i].Id() );
+            }
+        else
+            {
+            SetObjectFlagsL( ETrue, aItems[i], flags,
+                    RMenuNotifier::EItemsAddedRemoved );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::SetObjectFlagsL
+// ---------------------------------------------------------
+//
+void CMenuSrvAppScanner::SetObjectFlagsL( TBool aFlagValue, const TMenuItem& aItem,
+		const TMenuItem::TFlags& aFlag, const RMenuNotifier::TEvent& aEvent  )
+	{
+	TBool itemFlagPresent = (0 != (aItem.Flags() & aFlag));
+	if( aFlagValue != itemFlagPresent )
+		{
+		iEng.ModifiableObjectL( aItem.Id(), aEvent ).
+			 SetFlags( aFlag, aFlagValue );
+		}
+	}
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::UpdateMmcHistoryL
+// ---------------------------------------------------------
+//
+TUint CMenuSrvAppScanner::UpdateMmcHistoryL()
+    {
+    TUint mmcId = CurrentMmcId();
+    if( mmcId )
+    	{
+    	iMmcHistory->InsertL( mmcId );
+    	iMmcHistory->SaveL( iFs, KMenuMmcHistoryFname() );
+    	}
+    return mmcId;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::CurrentMmcId
+// ---------------------------------------------------------
+//
+TUint CMenuSrvAppScanner::CurrentMmcId() const
+    {
+    // Get mmc id. Errors are ignored.
+    TUint mmcId = 0;
+    TInt mmcDrive;
+    TInt err;
+    err = DriveInfo::GetDefaultDrive(
+    	    DriveInfo::EDefaultRemovableMassStorage, mmcDrive );
+    if ( !err )
+        {
+        TVolumeInfo volumeInfo;
+        err = iFs.Volume( volumeInfo, mmcDrive );
+        if( !err )
+            {
+            mmcId = volumeInfo.iUniqueID;
+            }
+        }
+    return mmcId;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::IsFileInDrive
+// ---------------------------------------------------------
+//
+TBool CMenuSrvAppScanner::IsFileInDrive(
+			const TDesC& aFileName,
+			const DriveInfo::TDefaultDrives& aDefaultDrive ) const
+    {
+    if ( aFileName.Length() )
+        {
+        TInt mmcDrive;
+        TInt err = DriveInfo::GetDefaultDrive(
+						aDefaultDrive, mmcDrive );
+        if ( !err )
+            {
+            TInt fileDrive;
+            err = RFs::CharToDrive( aFileName[0], fileDrive );
+            if ( !err && fileDrive == mmcDrive )
+                {
+                return ETrue;
+                }
+            }
+        }
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::IsAppInDrive
+// ---------------------------------------------------------
+//
+TBool CMenuSrvAppScanner::IsAppInDrive(
+        const CMenuSrvAppAttributes& aApaItem,
+		const DriveInfo::TDefaultDrives& aDefaultDrive ) const
+    {
+    TBool ret( EFalse );
+    if ( IsFileInDrive( aApaItem.GetFullName(), aDefaultDrive ) )
+    	{
+    	ret = ETrue;
+    	}
+    return ret;
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::IsInMmc
+// ---------------------------------------------------------
+//
+TBool CMenuSrvAppScanner::IsInMmc( const CMenuSrvAppAttributes& aApaItem ) const
+    {
+    return IsAppInDrive( aApaItem, DriveInfo::EDefaultRemovableMassStorage );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::IsInMassStorage
+// ---------------------------------------------------------
+//
+TBool CMenuSrvAppScanner::IsInMassStorage( const CMenuSrvAppAttributes& aApaItem ) const
+    {
+    return IsAppInDrive( aApaItem, DriveInfo::EDefaultMassStorage );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::IsInRomL
+// ---------------------------------------------------------
+//
+TBool CMenuSrvAppScanner::IsInRomL( const CMenuSrvAppAttributes& aApaItem ) const
+    {
+    return IsAppInDrive( aApaItem, DriveInfo::EDefaultRom );
+    }
+
+// ---------------------------------------------------------
+// CMenuSrvAppScanner::IsDriveInUse
+// ---------------------------------------------------------
+//
+TBool CMenuSrvAppScanner::IsDriveInUse(
+		const DriveInfo::TDefaultDrives& aDefaultDrive )
+    {
+    TBool inUse( EFalse );
+    TInt drive;
+
+    TInt err = DriveInfo::GetDefaultDrive( aDefaultDrive, drive );
+    if( err == KErrNone )
+		{
+		TUint status;
+		err =  DriveInfo::GetDriveStatus(  iFs, drive, status );
+		if( err == KErrNone
+				&& ( status & DriveInfo::EDriveInUse ) )
+			{
+			inUse = ETrue;
+			}
+		}
+
+	return inUse;
+    }
+
+//  End of File