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