diff -r 1a2a00e78665 -r 7feec50967db contentstorage/casrv/caappscanner/src/casrvappscanner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contentstorage/casrv/caappscanner/src/casrvappscanner.cpp Tue Mar 23 23:17:02 2010 +0200 @@ -0,0 +1,1003 @@ +/* +* 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: casrvappscanner.cpp +* +*/ + +#include +#include +#include +#include +#include + +#include "cadef.h" +#include "casrvappscanner.h" +#include "cautils.h" +#include "casrvmmchistory.h" +#include "pathinfo.h" +#include "casrvengutils.h" +#include "cainnerquery.h" +#include "cainnerentry.h" +#include "caarraycleanup.inl" +#include "castorageproxy.h" + +// ==================== LOCAL FUNCTIONS ==================== + +/** + * Identity function to search in an array of CCaInnerEntry. + * Identity is the ID. + * @param aLeft Search term. + * @param aRight Array item. + * @return ETrue if ID-s match. + */ +LOCAL_C TBool IdMatch( const CCaInnerEntry& aLeft, + const CCaInnerEntry& aRight ) + { + return aLeft.GetId() == aRight.GetId(); + } + +/** + * Identity function to search in an array of CCaInnerEntry. + * Identity is the ID. + * @param aLeft Search term. + * @param aRight Array item. + * @return ETrue if ID-s match. + */ +LOCAL_C TBool UidMatch( const CCaInnerEntry& aLeft, + const CCaInnerEntry& aRight ) + { + return aLeft.GetUid() == aRight.GetUid(); + } + +// ==================== MEMBER FUNCTIONS ==================== + +// --------------------------------------------------------- +// CCaSrvAppScanner::NewL +// --------------------------------------------------------- +// +CCaSrvAppScanner* CCaSrvAppScanner::NewL( CCaStorageProxy& aCaStorageProxy, + CCaSrvEngUtils& aUtils ) + { + CCaSrvAppScanner* scanner = new ( ELeave ) CCaSrvAppScanner( + aCaStorageProxy, aUtils ); + CleanupStack::PushL( scanner ); + scanner->ConstructL(); + CleanupStack::Pop( scanner ); + return scanner; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::~CCaSrvAppScanner +// --------------------------------------------------------- +// +CCaSrvAppScanner::~CCaSrvAppScanner() + { + Cancel(); + iApaLsSession.Close(); + iInstalledPackages.Close(); + delete iInstallNotifier; + delete iNotifier; + delete iMmcHistory; + iFs.Close(); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::CCaSrvAppScanner +// --------------------------------------------------------- +// +CCaSrvAppScanner::CCaSrvAppScanner( CCaStorageProxy& aCaStorageProxy, + CCaSrvEngUtils& aUtils ) : + CActive( CActive::EPriorityStandard ), + iCaStorageProxy( aCaStorageProxy ), iSrvEngUtils( aUtils ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::ConstructL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::ConstructL() + { + 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) CCaSrvMmcHistory(); + iMmcHistory->LoadL( iFs, KCaMmcHistoryFname() ); + // The notifier has its own session to apparc, instead of taking + // it as argument... :( + iNotifier = CApaAppListNotifier::NewL( + this, CActive::EPriorityStandard ); + iInstallNotifier = CCaInstallNotifier::NewL( + *this, CCaInstallNotifier::ESisInstallNotification ); + + User::LeaveIfError( iApaLsSession.Connect() ); + User::LeaveIfError( iApaLsSession.GetAllApps() ); // This is async. + iApaLsSession.RegisterListPopulationCompleteObserver( iStatus ); + iCollectionDownloadId = 0; + SetActive(); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RunL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::RunL() + { + User::LeaveIfError( iStatus.Int() ); // Handle errors in RunL. + // AppArc app scan complete, we have the app list. + UpdateApplicationEntriesL(); + InstallationNotifyL(); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::DoCancel +// --------------------------------------------------------- +// +void CCaSrvAppScanner::DoCancel() + { + iApaLsSession.CancelListPopulationCompleteObserver(); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RunError +// --------------------------------------------------------- +// +TInt CCaSrvAppScanner::RunError( TInt /*aError*/) + { + // Ignore the error (what else could we do?). + // When next AppArc update occurs, we will run again. + return KErrNone; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::UpdateApplicationItemL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::UpdateApplicationEntryL( + RPointerArray& aCaEntries, + const TCaAppAtributes& aApaItem, TUint aMmcId ) + { + TInt appuid = aApaItem.GetUid(); + RPointerArray resultArray; + CleanupResetAndDestroyPushL( resultArray ); + GetCaAppEntriesL( appuid, resultArray ); + + // This app is not in the storage, add it now. + // We don't add hidden items, there are too many of them! + // do not display Menu app + if( !resultArray.Count() + //TODO still needed? + && appuid != KMmUid3.iUid ) + { + AddAppEntryL( appuid, aMmcId ); + }//if + + // "hidden", "missing" and "lock_delete" flags update + for( TInt j = 0; j < resultArray.Count(); 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 + + UpdateAppEntryL( resultArray[j], aMmcId ); + TInt index = aCaEntries.Find( resultArray[j], + TIdentityRelation( IdMatch ) ); + if( index != KErrNotFound ) + { + delete aCaEntries[index]; + aCaEntries.Remove( index ); + } + }//for + CleanupStack::PopAndDestroy( &resultArray ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::UpdateAppEntryL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::UpdateAppEntryL( CCaInnerEntry* aEntry, TUint aMmcId ) + { + TBool toUpdate = HandleMmcAttrUpdateL( aEntry, aMmcId ); + toUpdate = HandleHiddenFlagUpdateL( aEntry ) || toUpdate; + toUpdate = HandleMissingFlagUpdate( aEntry ) || toUpdate; + toUpdate = HandleLockDeleteFlagUpdateL( aEntry ) || toUpdate; + toUpdate = SetApaAppInfoL( aEntry ) || toUpdate; + + if( iInstalledPackages.Find( aEntry->GetUid() ) != KErrNotFound ) + { + AddEntryToDownloadedCollectionL( aEntry->GetId() ); + toUpdate = HandleUsedFlagUpdateL( aEntry ) || toUpdate; + } + if( toUpdate ) + { + //update app in storage + iCaStorageProxy.AddL( aEntry ); + RemoveFromInstalledPackages( aEntry->GetUid() ); + } + } +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleHiddenFlagUpdateL +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::HandleHiddenFlagUpdateL( CCaInnerEntry* aItem ) + { + TBool toChange( EFalse ); + TBool itemHidden = ( 0 == ( aItem->GetFlags() & EVisible ) ); + if( itemHidden ) + { + aItem->SetFlags( aItem->GetFlags() | EVisible ); + toChange = ETrue; + } + return toChange; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleUsedFlagUpdateL +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::HandleUsedFlagUpdateL( CCaInnerEntry* aItem ) + { + if( aItem->GetFlags() & EUsed ) + { + aItem->SetFlags( aItem->GetFlags() & ~EUsed ); + return ETrue; + } + else + { + return EFalse; + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleMmcAttrUpdateL +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::HandleMmcAttrUpdateL( + CCaInnerEntry* aItem, TUint aMmcId ) + { + TBool toUpdate( ETrue ); + if( IsInMmc( TUid::Uid( aItem->GetUid() ) ) ) + { + //app is instaled on mmc - KCaAttrMmcId attribute update + TBuf uidString; + uidString.Format( KHexFormat, aMmcId ); + aItem->AddAttributeL( KCaAttrMmcId, uidString ); + } + else if ( IsInMassStorage( TUid::Uid( aItem->GetUid() ) ) ) + { + //its app installed on mass storage, we need to leave it + //in case of connecting usb in mass storage mode + aItem->AddAttributeL( KCaAttrMmcId, KCaMassStorage ); + } + else + { + RBuf attrVal; + attrVal.CleanupClosePushL(); + attrVal.CreateL( KCaMaxAttrValueLen ); + if( aItem->FindAttribute( KCaAttrMmcId, attrVal ) ) + { + aItem->RemoveAttributeL( KCaAttrMmcId ); + } + else + { + toUpdate = EFalse; + } + CleanupStack::PopAndDestroy( &attrVal ); + //its installed on c: drive - remove attribute + } + return toUpdate; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::UpdateApplicationItemsL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::InstallationNotifyL() + { + for( TInt i = iInstalledPackages.Count() - 1; i >= 0; i-- ) + { + NotifyL( iInstalledPackages[i] ); + iInstalledPackages.Remove( i ); + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::UpdateApplicationItemsL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::UpdateApplicationEntriesL() + { + TUint currentMmcId = UpdateMmcHistoryL(); + // get all Content arsenal enties with type application + RPointerArray resultArray; + CleanupResetAndDestroyPushL( resultArray ); + GetCaAppEntriesL( resultArray ); + RemoveSatAppL( resultArray ); + + RArray apaItems; + CleanupClosePushL( apaItems ); + GetApaItemsL( apaItems ); + RemoveSatApp( apaItems ); + + //for every item in apaAndCrItems array + for( TInt i = 0; i < apaItems.Count(); i++ ) + { + // if there was leave for any item we ignore it + // and proceed to the next one + TRAP_IGNORE(UpdateApplicationEntryL( + resultArray, apaItems[i], currentMmcId)); + } + // Here the big list cwith items that refer to missing apps. + HandleMissingItemsL( resultArray ); + HandleStubUpdatesL( ); + CleanupStack::PopAndDestroy( &apaItems ); + CleanupStack::PopAndDestroy( &resultArray ); + } + + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleStubUpdatesL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::HandleStubUpdatesL() + { + RPointerArray downloadedArray; + CleanupResetAndDestroyPushL( downloadedArray ); + + CCaInnerQuery* query = CCaInnerQuery::NewLC(); + CDesC16ArrayFlat* appType = new (ELeave) CDesC16ArrayFlat( 1 ); + CleanupStack::PushL( appType ); + appType->AppendL( KCaTypeApp ); + query->SetEntryTypeNames( appType ); + CleanupStack::Pop( appType ); + query->SetParentId( GetCollectionDownloadIdL() ); + query->SetFlagsOn( EVisible ); + query->SetFlagsOff( EMissing ); + query->SetFlagsOff( ERemovable ); + iCaStorageProxy.GetEntriesL( query, downloadedArray ); + + for(TInt i=0; iGetUid() ) ) + { + RemoveEntryFromDownloadedL( downloadedArray[i]->GetId() ); + } + } + + CleanupStack::PopAndDestroy( query ); + CleanupStack::PopAndDestroy( &downloadedArray ); + + } + + + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleLockDeleteFlagUpdateL +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::HandleLockDeleteFlagUpdateL( CCaInnerEntry* aItem ) + { + TBool toChange( EFalse ); + TBool isVisible = ( ( aItem->GetFlags() & EVisible ) != 0 ); + if( isVisible && IsInRom( aItem->GetUid() ) ) + { + if( ( aItem->GetFlags() & ERemovable ) != 0 ) + { + aItem->SetFlags( aItem->GetFlags() & ~ERemovable ); + toChange = ETrue; + } + } + else + { + if( ( aItem->GetFlags() & ERemovable ) == 0 ) + { + aItem->SetFlags( aItem->GetFlags() | ERemovable ); + toChange = ETrue; + } + } + return toChange; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleMissingFlagUpdateL +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::HandleMissingFlagUpdate( CCaInnerEntry* aItem ) + { + if( aItem->GetFlags() & EMissing ) + { + //application found so we unset "missing" flag + aItem->SetFlags( aItem->GetFlags() & ~EMissing ); + return ETrue; + } + else + { + return EFalse; + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RemoveSatApp +// --------------------------------------------------------- +// +void CCaSrvAppScanner::RemoveSatApp( RArray& aArray ) + { + TCaAppAtributes sat( KSatUid.iUid ); + TInt id = aArray.Find( sat, TCaAppAtributes::MatchItems ); + if( id != KErrNotFound ) + { + aArray.Remove( id ); + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RemoveSatApp +// --------------------------------------------------------- +// +void CCaSrvAppScanner::RemoveSatAppL( RPointerArray& aArray ) + { + CCaInnerEntry* sat = CCaInnerEntry::NewL(); + sat->SetUid( KSatUid.iUid ); + TInt index = aArray.Find( + sat, TIdentityRelation( UidMatch ) ); + if ( index != KErrNotFound ) + { + delete aArray[index]; + aArray.Remove( index ); + } + delete sat; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::GetApaItemsL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::GetApaItemsL( RArray& aArray ) + { + TApaAppInfo appInfo; + TApaAppCapabilityBuf appCap; + + User::LeaveIfError( iApaLsSession.GetAllApps( 0 ) ); + // 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 ) ); + // "Hidden" status according to AppArc. + if( !appCap().iAppIsHidden ) + { + TCaAppAtributes appAtributes( appInfo.iUid.iUid ); + aArray.AppendL( appAtributes ); + } + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::GetMcsItemsL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::GetCaAppEntriesL( + RPointerArray& aArray ) + { + CCaInnerQuery* allAppQuery = CCaInnerQuery::NewLC(); + CDesC16ArrayFlat* appType = new ( ELeave ) CDesC16ArrayFlat( 1 ); + CleanupStack::PushL( appType ); + appType->AppendL( KCaTypeApp ); + allAppQuery->SetEntryTypeNames( appType ); + CleanupStack::Pop( appType ); + iCaStorageProxy.GetEntriesL( allAppQuery, aArray ); + CleanupStack::PopAndDestroy( allAppQuery ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::GetMcsItemsL +// --------------------------------------------------------- +// +TInt CCaSrvAppScanner::GetCollectionDownloadIdL() + { + if( iCollectionDownloadId == 0 ) + { + RPointerArray resultArray; + CleanupResetAndDestroyPushL( resultArray ); + CCaInnerQuery* allAppQuery = CCaInnerQuery::NewLC(); + CDesC16ArrayFlat* appType = new ( ELeave ) CDesC16ArrayFlat( 1 ); + CleanupStack::PushL( appType ); + appType->AppendL( KCaTypeCollectionDownload ); + allAppQuery->SetEntryTypeNames( appType ); + CleanupStack::Pop( appType ); + iCaStorageProxy.GetEntriesL( allAppQuery, resultArray ); + CleanupStack::PopAndDestroy( allAppQuery ); + if( resultArray.Count() ) + { + iCollectionDownloadId = resultArray[0]->GetId(); + } + CleanupStack::PopAndDestroy( &resultArray ); + } + return iCollectionDownloadId; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::GetMcsItemsL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::GetCaAppEntriesL( TInt aUid, + RPointerArray& aArray ) + { + CCaInnerQuery* allAppQuery = CCaInnerQuery::NewLC(); + allAppQuery->SetUid( aUid ); + iCaStorageProxy.GetEntriesL( allAppQuery, aArray ); + CleanupStack::PopAndDestroy( allAppQuery ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleAppListEvent +// --------------------------------------------------------- +// +void CCaSrvAppScanner::HandleAppListEvent( TInt /*aEvent*/) + { + // We only have one event, EAppListChanged. + // Call back RunL async, to requeue and initiate rescan. + if( !IsActive() ) + { + ScheduleScan(); + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleInstallNotifyL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::HandleInstallNotifyL( TInt aUid ) + { + NotifyL( aUid ); + RArray uids; + CleanupClosePushL( uids ); + + Swi::RSisRegistrySession iSisRegSession; + User::LeaveIfError( iSisRegSession.Connect() ); + CleanupClosePushL( iSisRegSession ); + + // Open sis package entry related to aUid + Swi::RSisRegistryEntry packageEntry; + if( KErrNone + == packageEntry.Open( iSisRegSession, TUid::Uid( aUid ) ) ) + { + CleanupClosePushL( packageEntry ); + + // Get packageEntry's embedded sis' + RPointerArray embedded; + CleanupClosePushL( embedded ); + packageEntry.EmbeddedPackagesL( embedded ); + if( embedded.Count() ) + { + // For each embadded sis we notify storage - recursive call + for( TInt i = 0; i < embedded.Count(); ++i ) + { + HandleInstallNotifyL( embedded[i]->Uid().iUid ); + } + } + else + { + // There are no embaddes sis', so we can notify storage + // of changes in apps included in packageEntry + NotifyL( packageEntry ); + } + embedded.ResetAndDestroy(); + CleanupStack::PopAndDestroy( &embedded ); + CleanupStack::PopAndDestroy( &packageEntry ); + } + CleanupStack::PopAndDestroy( &iSisRegSession ); + CleanupStack::PopAndDestroy( &uids ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::NotifyL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::NotifyL( Swi::RSisRegistryEntry & aPackageEntry ) + { + // Get sids ( == uids of exetucables included in aPackageEntry ) + RArray sids; + CleanupClosePushL( sids ); + aPackageEntry.SidsL( sids ); + if( sids.Count() ) + { + // For each sid we notify storage + for( TInt i = 0; i < sids.Count(); ++i ) + { + iInstalledPackages.Append( sids[i].iUid ); + } + } + CleanupStack::PopAndDestroy( &sids ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::NotifyL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::NotifyL( TInt aAppUid ) + { + // Get entries for given aAppUid + RPointerArray resultArray; + CleanupResetAndDestroyPushL( resultArray ); + GetCaAppEntriesL( aAppUid, resultArray ); + if( resultArray.Count() ) + { + iCaStorageProxy.AddL( resultArray[0] ); + } + CleanupStack::PopAndDestroy( &resultArray ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::AddEntryToDownloadedCollectionL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::AddEntryToDownloadedCollectionL( TInt aEntryId ) + { + TCaOperationParams params = { TCaOperationParams::EPrepend, GetCollectionDownloadIdL(), 0 // not used + }; + + RArray entryIds; + CleanupClosePushL( entryIds ); + entryIds.AppendL( aEntryId ); + iCaStorageProxy.OrganizeL( entryIds, params ); + + CleanupStack::PopAndDestroy( &entryIds ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RemoveToDownloadedCollectionL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::RemoveEntryFromDownloadedL( TInt aEntryId ) + { + TCaOperationParams params = { TCaOperationParams::ERemove, GetCollectionDownloadIdL(), 0 // not used + }; + + RArray entryIds; + CleanupClosePushL( entryIds ); + entryIds.AppendL( aEntryId ); + iCaStorageProxy.OrganizeL( entryIds, params ); + + CleanupStack::PopAndDestroy( &entryIds ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::ScheduleScan +// --------------------------------------------------------- +// +void CCaSrvAppScanner::ScheduleScan() + { + if( !IsActive() ) + { + TRequestStatus* ownStatus = &iStatus; + *ownStatus = KRequestPending; + SetActive(); + User::RequestComplete( ownStatus, KErrNone ); + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::AddAppItemL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::AddAppEntryL( TUint aUid, TUint aCurrentMmcId ) + { + // Now add the app entry. + CCaInnerEntry* appEntry = CCaInnerEntry::NewLC(); + + appEntry->SetEntryTypeNameL( KCaTypeApp ); + appEntry->SetUid( aUid ); + appEntry->SetFlags( EVisible ); + appEntry->SetRole( EItemEntryRole ); + + SetApaAppInfoL( appEntry ); + HandleLockDeleteFlagUpdateL( appEntry ); + HandleMmcAttrUpdateL( appEntry, aCurrentMmcId ); + + iCaStorageProxy.AddL( appEntry ); + if( iInstalledPackages.Find( aUid ) != KErrNotFound ) + { + AddEntryToDownloadedCollectionL( appEntry->GetId() ); + } + RemoveFromInstalledPackages( aUid ); + + CleanupStack::PopAndDestroy( appEntry ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RemoveFromInstalledPackages +// --------------------------------------------------------- +// +void CCaSrvAppScanner::RemoveFromInstalledPackages( TUint aUid ) + { + TInt appIndex = iInstalledPackages.Find( aUid ); + if( appIndex != KErrNotFound ) + { + iInstalledPackages.Remove( appIndex ); + } + } + +// --------------------------------------------------------------------------- +// CCaSrvAppScanner::IsMidletL +// Checks if given app is midlet by reading the apptype uid (2nd uid) +// --------------------------------------------------------------------------- +// +TBool CCaSrvAppScanner::SetApaAppInfoL( CCaInnerEntry* aEntry ) + { + TBool changed( EFalse ); + TApaAppInfo info; + if( KErrNone == iSrvEngUtils.GetAppInfo( *aEntry, info ) ) + { + RBuf attrVal; + attrVal.CleanupClosePushL(); + attrVal.CreateL( KCaMaxAttrValueLen ); + aEntry->FindAttribute( KCaAttrLongName, attrVal ); + if( attrVal.Compare( info.iCaption ) != KErrNone + || aEntry->GetText().Compare( info.iShortCaption ) + != KErrNone ) + { + aEntry->SetTextL( info.iShortCaption ); + aEntry->AddAttributeL( KCaAttrLongName, info.iCaption ); + changed = ETrue; + } + CleanupStack::PopAndDestroy( &attrVal ); + } + return changed; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::HandleMissingItemsL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::HandleMissingItemsL( + RPointerArray& aCaEntries ) + { + for( TInt i = 0; i < aCaEntries.Count(); i++ ) + { + const TInt id = aCaEntries[i]->GetId(); + TUint mmcId = 0; + RBuf attrVal; + attrVal.CleanupClosePushL(); + attrVal.CreateL( KCaMaxAttrValueLen ); + if( aCaEntries[i]->FindAttribute( KCaAttrMmcId(), attrVal ) ) + { + MenuUtils::GetTUint( attrVal, mmcId ); + if( mmcId && KErrNotFound != iMmcHistory->Find( mmcId ) + && mmcId != CurrentMmcId() ) + { + // This item is on an MMC which is currently in the MMC history. + // Set it "missing" but keep it. + AddObjectFlagL( aCaEntries[i], EMissing ); + } + else if ( attrVal == KCaMassStorage() + && IsDriveInUse( DriveInfo::EDefaultMassStorage ) ) + { + AddObjectFlagL( aCaEntries[i], EMissing ); + } + else + { + RemoveAppL( aCaEntries[i] ); + } + } + else + { + RemoveAppL( aCaEntries[i] ); + } + CleanupStack::PopAndDestroy( &attrVal ); + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::RemoveAppL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::RemoveAppL( CCaInnerEntry* aAppEntry ) + { + RArray idsToRemove; + CleanupClosePushL( idsToRemove ); + idsToRemove.AppendL( aAppEntry->GetId() ); + iCaStorageProxy.RemoveL( idsToRemove ); + CleanupStack::PopAndDestroy( &idsToRemove ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::AddObjectFlagL +// --------------------------------------------------------- +// +void CCaSrvAppScanner::AddObjectFlagL( + CCaInnerEntry* aEntry, const TInt& aFlags ) + { + TBool itemFlagPresent = ( 0 != ( aEntry->GetFlags() & aFlags ) ); + if( !itemFlagPresent ) + { + aEntry->SetFlags( aEntry->GetFlags() | aFlags ); + iCaStorageProxy.AddL( aEntry ); + } + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::UpdateMmcHistoryL +// --------------------------------------------------------- +// +TUint CCaSrvAppScanner::UpdateMmcHistoryL() + { + TUint mmcId = CurrentMmcId(); + if( mmcId ) + { + iMmcHistory->InsertL( mmcId ); + iMmcHistory->SaveL( iFs, KCaMmcHistoryFname() ); + } + return mmcId; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::CurrentMmcId +// --------------------------------------------------------- +// +TUint CCaSrvAppScanner::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; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::IsFileInDrive +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::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; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::IsAppInDrive +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::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; + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::IsInMmc +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::IsInMmc( const TUid aUid ) const + { + return IsAppInDrive( aUid, DriveInfo::EDefaultRemovableMassStorage ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::IsInMassStorage +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::IsInMassStorage( const TUid aUid ) const + { + return IsAppInDrive( aUid, DriveInfo::EDefaultMassStorage ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::IsInRom +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::IsInRom( TInt aUid ) + { + return IsAppInDrive( TUid::Uid( aUid ), DriveInfo::EDefaultRom ); + } + +// --------------------------------------------------------- +// CCaSrvAppScanner::IsDriveInUse +// --------------------------------------------------------- +// +TBool CCaSrvAppScanner::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 +// --------------------------------------------------------- +// +TCaAppAtributes::TCaAppAtributes( TUint aUid ) + { + iUid = aUid; + } + +// --------------------------------------------------------- +// TAppAtributes::GetUid +// --------------------------------------------------------- +// +TUint TCaAppAtributes::GetUid() const + { + return iUid; + } + +// --------------------------------------------------------- +// TAppAtributes::MatchItems +// --------------------------------------------------------- +// +TBool TCaAppAtributes::MatchItems( const TCaAppAtributes& item1, + const TCaAppAtributes& item2 ) + { + return item1.GetUid() == item2.GetUid(); + } +