diff -r 000000000000 -r 79c6a41cd166 menucontentsrv/srvsrc/menusrvappscanner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/menucontentsrv/srvsrc/menusrvappscanner.cpp Thu Dec 17 08:54:17 2009 +0200 @@ -0,0 +1,1358 @@ +/* +* 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 +#include +#include +#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" + +_LIT( KMenuOne, "1" ); +_LIT( KMenuAttrMmcId, "mmc_id" ); +_LIT( KMenuMassStorage, "mass_storage" ); +_LIT( KMenuMmcHistoryFname, "mmchistory" ); +_LIT( KZDrive, "Z" ); + +// ==================== 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 ) + { + CMenuSrvAppScanner* scanner = new (ELeave) CMenuSrvAppScanner( aEng ); + CleanupStack::PushL( scanner ); + scanner->ConstructL(); + CleanupStack::Pop( scanner ); + return scanner; + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::~CMenuSrvAppScanner +// --------------------------------------------------------- +// +CMenuSrvAppScanner::~CMenuSrvAppScanner() + { + Cancel(); + iApaLsSession.Close(); + delete iMcsSatNotifier; + delete iNotifier; + iEng.DequeueOperation( *this ); + delete iMmcHistory; + iFs.Close(); + iWidgetSession.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 ) +: CActive( CActive::EPriorityStandard ), iEng( aEng ) + { + 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 ); + User::LeaveIfError( iApaLsSession.Connect() ); + User::LeaveIfError( iApaLsSession.GetAllApps() ); // This is async. + User::LeaveIfError( iWidgetSession.Connect() ); + + 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 ); + + iApaLsSession.RegisterListPopulationCompleteObserver( iStatus ); + SetActive(); + 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. + iEng.QueueOperationL( *this ); + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::DoCancel +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::DoCancel() + { + iApaLsSession.CancelListPopulationCompleteObserver(); + } + +// --------------------------------------------------------- +// 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 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 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 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 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& aMcsItems, const TAppAtributes& aApaItem, + TUint aMmcId, TBool isLegacy) + { + RArray mcsUidItems; + CleanupClosePushL( mcsUidItems ); + TInt appuid = aApaItem.GetUid(); + GetMcsAppItemsL( isLegacy, appuid, 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.iUid ) + { + if( appuid == KSatUid.iUid ) + { + if( CMcsSatHandler::CheckVisibility() ) + { + AddAppItemL( appuid, aMmcId ); + } + } + else + { + AddAppItemL( appuid, aMmcId ); + GetMcsAppItemsL( isLegacy, appuid, 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 uidString; + MenuSrvUtil::UidToStringL( appuid, 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, appuid, aMmcId ); + HandleNativeAttrUpdateL( item, appuid ); + + // "hidden" flag handling. + HandleHiddenFlagUpdateL( item, appuid, isApaItemHidden ); + + // "missing" flag handling + HandleMissingFlagUpdateL( item ); + + //"lock_delete" flag handling + HandleLockDeleteFlagUpdateL(item, appuid); + // if item was just added to MCS it is not present in aMcsItems + // so we cannot remove it + TInt index = aMcsItems.Find( item, TIdentityRelation( IdMatch ) ); + if ( index != KErrNotFound ) + { + aMcsItems.Remove( index ); + } + }//for + CleanupStack::PopAndDestroy( &mcsUidItems ); + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::HandleHiddenFlagUpdateL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::HandleHiddenFlagUpdateL( const TMenuItem & aItem, + TInt & aAppUid, TBool aApaItemHidden ) + { + TBool itemHidden = (0 != (aItem.Flags() & TMenuItem::EHidden)); + if (aAppUid == KSatUid.iUid) + { + if (itemHidden == CMcsSatHandler::CheckVisibility()) + { + iEng.ModifiableObjectL(aItem.Id(), RMenuNotifier::EItemsAddedRemoved). + SetFlags( TMenuItem::EHidden, !CMcsSatHandler::CheckVisibility()); + } + } + else if (itemHidden != aApaItemHidden) + { + iEng.ModifiableObjectL(aItem.Id(), RMenuNotifier::EItemsAddedRemoved). + SetFlags( TMenuItem::EHidden, aApaItemHidden ); + } + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::HandleNativeAttrUpdateL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::HandleNativeAttrUpdateL( + const TMenuItem& aItem, TInt aUid ) + { + //we need this to delete uninstalled java app item + if( ( IsMidlet( TUid::Uid( aUid ) ) + || iWidgetSession.IsWidget( TUid::Uid( aUid ) ) ) + && iEng.ObjectL( aItem.Id() ).GetNative() ) + { + iEng.ModifiableObjectL( aItem.Id(), + RMenuNotifier::EItemsNone ).SetNative( EFalse ); + } + } + + +// --------------------------------------------------------- +// CMenuSrvAppScanner::HandleMmcAttrUpdateL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::HandleMmcAttrUpdateL( + const TMenuItem& aItem, TInt aUid, TUint aMmcId ) + { + if ( IsMmcApp( TUid::Uid( aUid ) ) ) + { + //app is instaled on mmc - KMenuAttrMmcId attribute update + TBuf uidString; + uidString.Format( KHexFormat, aMmcId ); + iEng.ModifiableObjectL( aItem.Id(), RMenuNotifier::EItemsAddedRemoved ). + SetAttributeL( KMenuAttrMmcId, uidString, EFalse ); + } + else if ( IsMassStorageApp( TUid::Uid( aUid ) ) + && IsMidlet( TUid::Uid( aUid ) ) ) + { + //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 mcsItems; + CleanupClosePushL( mcsItems ); + GetMcsAppItemsL( mcsItems ); + RArray apaAndCrItems; + CleanupClosePushL( apaAndCrItems ); + GetApaItemsL( apaAndCrItems ); + GetCrItemsL( apaAndCrItems ); + TBool isLegacy = iEng.GetOnceLegacyFormat(); + + + //for every item in apaAndCrItems array + for ( TInt i = ( apaAndCrItems.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, apaAndCrItems[i], currentMmcId, isLegacy)); + } + // Here the big list contains menu items that refer to missing apps. + HandleMissingItemsL( mcsItems ); + CleanupStack::PopAndDestroy( &apaAndCrItems ); + CleanupStack::PopAndDestroy( &mcsItems ); + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::HandleLockDeleteFlagUpdateL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::HandleLockDeleteFlagUpdateL( + const TMenuItem& aItem, TInt aUid ) + { + TBool isHidden = ( ( iEng.ObjectL( aItem.Id() ) + .Flags() & TMenuItem::EHidden ) != 0 ); + if ( !isHidden && IsInRomL( aUid ) ) + { + 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::IsInRomL +// --------------------------------------------------------- +// +TBool CMenuSrvAppScanner::IsInRomL( TInt aUid ) + { + TBool inROM = EFalse; + TApaAppInfo appInfo; + if( iApaLsSession.GetAppInfo( appInfo, TUid::Uid( aUid ) ) == KErrNone ) + { + RBuf path; + CleanupClosePushL( path ); + path.CreateL( appInfo.iFullName ); + path.Replace( 0, 1, KZDrive ); + if( BaflUtils::FileExists( iFs, path ) ) + { + inROM = ETrue; + } + CleanupStack::PopAndDestroy( &path ); + } + return inROM; + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::GetCrItemsL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::GetCrItemsL( RArray& aArray ) + { + TBuf 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, + RArray& 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, + RArray& aArray ) + { + TLex appUidDescriptor(aHiddenAppUid); + TUint hiddenAppUid( 0 ); + appUidDescriptor.Val( hiddenAppUid, EHex ); + if ( hiddenAppUid ) + { + //all applications in descriptor are hidden + TAppAtributes appAtributes( hiddenAppUid, ETrue ); + TInt id = aArray.Find(appAtributes, TAppAtributes::MatchItems ); + if ( id != KErrNotFound ) + { + aArray[id].SetHidden( ETrue ); + } + } + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::GetApaItemsL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::GetApaItemsL( RArray& aArray ) + { + TApaAppInfo appInfo; + TApaAppCapabilityBuf appCap; + TInt screenNumber; + + User::LeaveIfError( iApaLsSession.GetAllApps() ); + // for every application get uid, hidden and missing attribute + // and add to aArray. + while ( KErrNone == iApaLsSession.GetNextApp( appInfo ) ) + { + User::LeaveIfError( iApaLsSession.GetAppCapability + ( appCap, appInfo.iUid ) ); + User::LeaveIfError( iApaLsSession.GetDefaultScreenNumber + ( screenNumber, appInfo.iUid ) ); + // "Hidden" status according to AppArc. + TBool appHidden = appCap().iAppIsHidden || screenNumber != 0; + + TAppAtributes appAtributes( appInfo.iUid.iUid, appHidden ); + aArray.AppendL( appAtributes ); + } + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::GetMcsItemsL +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::GetMcsAppItemsL( RArray& 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& aArray ) + { + TInt root; + iEng.RootFolderL( root ); + TMenuSrvTypeAttrFilter appFilter; + appFilter.SetType( KMenuTypeApp() ); + TBuf 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( TUint aUid ) + { + // Find a folder for this app. + TInt folder(0); + + TApaAppCapabilityBuf capability; + User::LeaveIfError(iApaLsSession.GetAppCapability( capability, TUid::Uid( aUid ))); + + if ( capability().iGroupName.Length() ) + { + // appgroup_name is defined for this app. Find or create folder. + AppGroupFolderL( capability().iGroupName, 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( + TUint aUid, + TUint aCurrentMmcId ) + { + TInt folder = CreateInstallFolderL( aUid ); + // Now add the app item. + CMenuEngObject* object = iEng.NewObjectL( KMenuTypeApp() ); + CleanupStack::PushL( object ); + TBuf uidString; + _LIT(KHexFormat, "0x%X"); + uidString.Format( KHexFormat, aUid ); + + object->SetAttributeL( KMenuAttrUid(), uidString, EFalse ); + if ( aCurrentMmcId && IsMmcApp( TUid::Uid( aUid ) ) ) + { + // This app is on the MMC, set the "mmc_id" attribute. + uidString.Format( KHexFormat, aCurrentMmcId ); + object->SetAttributeL( KMenuAttrMmcId, uidString, EFalse ); + } + if( IsMidlet( TUid::Uid( aUid ) ) + || iWidgetSession.IsWidget( TUid::Uid( aUid ) ) ) + { + //we need this to delete uninstalled java or wrt widget app item + object->SetNative( EFalse ); + if ( !IsMmcApp( TUid::Uid( aUid ) ) + && IsMassStorageApp( TUid::Uid( aUid ) ) ) + { + object->SetAttributeL( KMenuAttrMmcId, KMenuMassStorage, EFalse ); + } + } + EnsureFolderWritableL( folder ); + iEng.AddL( *object, folder, 0 ); + CleanupStack::Pop( object ); + } + +// --------------------------------------------------------------------------- +// CMenuSrvAppScanner::IsMidletL +// Checks if given app is midlet by reading the apptype uid (2nd uid) +// --------------------------------------------------------------------------- +// +TBool CMenuSrvAppScanner::IsMidlet( const TUid aAppUid ) + { + const TUid KMidletType = { 0x10210E26 }; + TUid typeuid = KNullUid; + + if ( KErrNone == iApaLsSession.GetAppType( typeuid, aAppUid ) ) + { + if ( typeuid == KMidletType ) + { + return ETrue; + } + } + return EFalse; + } + + +// --------------------------------------------------------- +// 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 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 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 +// --------------------------------------------------------- +// +void CMenuSrvAppScanner::HandleMissingItemsL +( const RArray& aItems ) + { + for ( TInt i = 0; i < aItems.Count(); i++ ) + { + const TInt id = aItems[i].Id(); + TUint mmcId = 0; + TPtrC val; + TBool dummy; + if( iEng.ObjectL( 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. + SetObjectFlagsL( ETrue, aItems[i], TMenuItem::EMissing, + RMenuNotifier::EItemsAddedRemoved ); + } + else if ( val == KMenuMassStorage() + && IsDriveInUse( DriveInfo::EDefaultMassStorage ) ) + { + SetObjectFlagsL( ETrue, aItems[i], TMenuItem::EMissing, + RMenuNotifier::EItemsAddedRemoved ); + } + else + { + iEng.RemoveL( id ); + } + } + else + { + // This item is not on MMC or its MMC has been purged from the MMC + // history. Hide the item. + SetObjectFlagsL( EFalse, aItems[i], TMenuItem::ELockDelete ); + + if( iEng.ObjectL( id ).GetNative() ) + { + SetObjectFlagsL( ETrue, aItems[i], TMenuItem::EHidden, + RMenuNotifier::EItemsAddedRemoved ); + } + else + { + iEng.RemoveL( id ); + } + } + } + } + +// --------------------------------------------------------- +// 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 TUid aUid, + const DriveInfo::TDefaultDrives& aDefaultDrive ) const + { + TBool ret( EFalse ); + TApaAppInfo info; + TInt err = iApaLsSession.GetAppInfo( info, aUid ); + if ( !err && IsFileInDrive( info.iFullName, aDefaultDrive ) ) + { + ret = ETrue; + } + return ret; + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::IsMmcApp +// --------------------------------------------------------- +// +TBool CMenuSrvAppScanner::IsMmcApp( const TUid aUid ) const + { + return IsAppInDrive( aUid, DriveInfo::EDefaultRemovableMassStorage ); + } + +// --------------------------------------------------------- +// CMenuSrvAppScanner::IsMassStorageApp +// --------------------------------------------------------- +// +TBool CMenuSrvAppScanner::IsMassStorageApp( const TUid aUid ) const + { + return IsAppInDrive( aUid, DriveInfo::EDefaultMassStorage ); + } + +// --------------------------------------------------------- +// 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; + } + +// ==================== MEMBER FUNCTIONS ==================== + +// --------------------------------------------------------- +// TAppAtributes::TAppAtributes +// --------------------------------------------------------- +// +TAppAtributes::TAppAtributes ( TUint aUid, TBool aHidden/*, TBool aMissing*/) + { + iUid = aUid; + iHidden = aHidden; + /*iMissing = aMissing;*/ + } + +// --------------------------------------------------------- +// TAppAtributes::GetUid +// --------------------------------------------------------- +// +TUint TAppAtributes::GetUid() const + { + return iUid; + } + +// --------------------------------------------------------- +// TAppAtributes::IsHidden +// --------------------------------------------------------- +// +TBool TAppAtributes::IsHidden() const + { + return iHidden; + } +// --------------------------------------------------------- +// TAppAtributes::SetHidden +// --------------------------------------------------------- +// +void TAppAtributes::SetHidden( TBool aHidden ) + { + iHidden = aHidden; + } + +// --------------------------------------------------------- +// TAppAtributes::MatchItems +// --------------------------------------------------------- +// +TBool TAppAtributes::MatchItems(const TAppAtributes& item1, + const TAppAtributes& item2) + { + TBool result( EFalse ); + TUint uid1(item1.GetUid()); + TUint uid2(item2.GetUid()); + if ( uid1 == uid2 ) + { + result = ETrue; + } + return result; + } + + + +// End of File