diff -r 4bc7b118b3df -r 397d00875918 tstaskmonitor/server/src/tsfswdatalist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tstaskmonitor/server/src/tsfswdatalist.cpp Thu May 27 13:11:12 2010 +0300 @@ -0,0 +1,570 @@ +/* +* Copyright (c) 2008 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: File containing application list classes + * +*/ + + +//INCLUDES: +#define __E32SVR_H__ +#include "tsfswdatalist.h" +#include "tsfswengine.h" +#include // for CleanupResetAndDestroyPushL +#include +#include +#include +#include +#include +#include +#include // avkon +#include // fbsbitmap +#include + +// size for the created app icons +const TInt KAppIconWidth = 128; +const TInt KAppIconHeight = 128; + +//uids to be hidden +const TUid KHsApplicationUid = {0x20022F35}; +const TUid KTelephoneUid = {0x100058B3}; + +// ================= MEMBER FUNCTIONS ======================= + +// -------------------------------------------------------------------------- +// CTsFswDataList::NewL +// -------------------------------------------------------------------------- +// +CTsFswDataList* CTsFswDataList::NewL(CTsFswEngine& aEngine) + { + CTsFswDataList* self = new (ELeave) CTsFswDataList(aEngine); + CleanupStack::PushL (self ); + self->ConstructL ( ); + CleanupStack::Pop ( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::CTsFswDataList +// -------------------------------------------------------------------------- +// +CTsFswDataList::CTsFswDataList(CTsFswEngine& aEngine) : + iEngine(aEngine) + { + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::~CTsFswDataList +// -------------------------------------------------------------------------- +// +CTsFswDataList::~CTsFswDataList( ) + { + iData.ResetAndDestroy(); + iAppArcSession.Close(); + iWsSession.Close(); + iHiddenUids.Close(); + RFbsSession::Disconnect(); + RAknIconSrvClient::Disconnect(); + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::ConstructL +// -------------------------------------------------------------------------- +// +void CTsFswDataList::ConstructL( ) + { + User::LeaveIfError( iWsSession.Connect() ); + User::LeaveIfError( iAppArcSession.Connect() ); + iHiddenUids.AppendL( KHsApplicationUid ); + iHiddenUids.AppendL( KTelephoneUid ); + User::LeaveIfError(RFbsSession::Connect()); + RAknIconSrvClient::Connect(); + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::FswDataL +// -------------------------------------------------------------------------- +// +const RTsFswArray& CTsFswDataList::FswDataL() + { + // check the dirty flag and refresh if needed + if ( iTaskListDirty ) + { + CollectTasksL(); + // dirty flag is cleared in the above call + } + + return iData; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::CollectTasksL +// -------------------------------------------------------------------------- +// +TBool CTsFswDataList::CollectTasksL() + { + // clear dirty flag + iTaskListDirty = EFalse; + TBool changed = EFalse; + + RTsFswArray newAppsList; + + CleanupResetAndDestroyPushL(newAppsList); + + CollectAppsL(newAppsList); + + changed |= FitDataToListL(newAppsList, EFalse); + + CleanupStack::PopAndDestroy( &newAppsList ); + + return changed; + } + + +// -------------------------------------------------------------------------- +// CTsFswDataList::SetDirty() +// -------------------------------------------------------------------------- +// +void CTsFswDataList::SetDirty() + { + iTaskListDirty = ETrue; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::SetAppDataRefreshNeeded() +// -------------------------------------------------------------------------- +// +void CTsFswDataList::SetAppDataRefreshNeeded() + { + iAppDataRefreshNeeded = ETrue; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::MoveEntryAtStart +// -------------------------------------------------------------------------- +// +void CTsFswDataList::MoveEntryAtStart(TInt aAppId, TBool /*aWidget*/) + { + TInt appId(0); + //check embeded case + + TInt wgId(0); + CApaWindowGroupName::FindByAppUid(TUid::Uid(aAppId), iWsSession, wgId); + TInt parentWgId = FindMostTopParentWgId( wgId ); + if( parentWgId != KErrNotFound ) + { + TUid appUid = TUid::Uid(0); + AppUidForWgId(parentWgId, appUid); + appId = appUid.iUid; + } + + + if( !appId ) + { + appId = aAppId; + } + + for ( TInt i = 0; i < iData.Count(); ++i ) + { + if( iData[i]->AppUid().iUid == appId ) + { + CTsFswEntry* entry = iData[i]; + iData.Remove(i); + iData.Insert(entry, 0); + iOrderChanged = ETrue; + break; + } + } + } + +// -------------------------------------------------------------------------- +// CTsFswDataList:: +// -------------------------------------------------------------------------- +// +void CTsFswDataList::CollectAppsL(RTsFswArray& aAppsList) + { + + + // update app data if needed + // (usually on startup and when new apps might have been installed) + if ( iAppDataRefreshNeeded ) + { + + iAppArcSession.GetAllApps(); + iAppDataRefreshNeeded = EFalse; + } + + // get all window groups + RArray allWgIds; + CleanupClosePushL( allWgIds ); + User::LeaveIfError( iWsSession.WindowGroupList( 0, &allWgIds ) ); + + TInt count = allWgIds.Count(); + for ( TInt i = 0; i < count; ++i ) + { + // ignore uninteresting entries (e.g. embedded apps) + if ( allWgIds[i].iParentId > 0 ) + { + continue; + } + + // get window group name + TInt wgId = allWgIds[i].iId; + CApaWindowGroupName* windowName = + CApaWindowGroupName::NewLC( iWsSession, wgId ); + TUid appUid = windowName->AppUid(); + + // ignore entries with null uid + if ( !appUid.iUid ) + { + CleanupStack::PopAndDestroy( windowName ); + continue; + } + + // add item to task list if it is not hidden + if ( !windowName->Hidden() && !IsHiddenUid(appUid) ) + { + AddEntryL(wgId, appUid, windowName, aAppsList, EFalse); + } + CleanupStack::PopAndDestroy( windowName ); + } + CleanupStack::PopAndDestroy( &allWgIds ); + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::AddEntryL +// -------------------------------------------------------------------------- +// +TBool CTsFswDataList::AddEntryL( TInt aWgId, const TUid& aAppUid, + CApaWindowGroupName* aWgName, RTsFswArray& aNewList, + TBool /*aIsWidget*/ ) + { + TBool changed = EFalse; + CTsFswEntry* entry = CTsFswEntry::NewLC(); + entry->SetWgId( aWgId ); + entry->SetAppUid( aAppUid ); + + // check if present in old list and if yes then take some of the old data + TBool found = ConsiderOldDataL( *entry, aAppUid, changed, aNewList ); + + // if not present previously then find out app name + // and check if screenshot is already available + if ( !found ) + { + // when adding a new entry to the list it is changed for sure + changed = ETrue; + HBufC* name = FindAppNameLC( aWgName, aAppUid, aWgId ); + if ( name ) + { + entry->SetAppNameL( *name ); + } + CleanupStack::PopAndDestroy( name ); + + if ( aWgName ) + { + entry->SetCloseableApp( !aWgName->IsSystem() ); + } + CFbsBitmap* iconBitmap = NULL; + CFbsBitmap* iconMask = NULL; + GetAppIconL(aAppUid, iconBitmap, iconMask); + //transfer ownership to entry + entry->SetAppIcon( iconBitmap, iconMask ); + } + + // add to new list, ownership is transferred + aNewList.AppendL( entry ); + CleanupStack::Pop( entry ); + return changed; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::ConsiderOldDataL +// -------------------------------------------------------------------------- +// +TBool CTsFswDataList::ConsiderOldDataL( CTsFswEntry& aEntry, + const TUid& aAppUid, + TBool& aChanged, + RTsFswArray& aNewList ) + { + for ( TInt entryIdx = 0, oldCount = iData.Count(); + entryIdx < oldCount; ++entryIdx ) + { + // Enough to check appuid, no need to bother with wgid as the + // screenshot handle is up-to-date or will be updated later anyway. + if ( iData[entryIdx]->AppUid() == aAppUid ) + { + iData[entryIdx]->SetWgId( aEntry.WgId()); + // if positions do not match then the list is different than before + if ( entryIdx != aNewList.Count() ) + { + aChanged = ETrue; + } + CTsFswEntry* oldEntry = iData[entryIdx]; + aEntry.SetAppNameL( oldEntry->AppName() ); + aEntry.SetCloseableApp( oldEntry->CloseableApp() ); + return ETrue; + } + } + return EFalse; + } + + +// -------------------------------------------------------------------------- +// CTsFswDataList::FindParentWgId +// -------------------------------------------------------------------------- +// +TInt CTsFswDataList::FindParentWgId( TInt aWgId ) + { + TInt parent( KErrNotFound ); + RArray allWgIds; + // Ask for window group list from RWsSession + TInt error = iWsSession.WindowGroupList( 0, &allWgIds ); + if ( !error ) + { + TInt count( allWgIds.Count() ); + for ( TInt i( 0 ); i < count; i++ ) + { + RWsSession::TWindowGroupChainInfo info = allWgIds[i]; + if ( info.iId == aWgId && info.iParentId > 0) + { + parent = info.iParentId; + break; + } + } + } + allWgIds.Close(); + return parent; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::FindMostTopParentWgId +// -------------------------------------------------------------------------- +// +TInt CTsFswDataList::FindMostTopParentWgId( TInt aWgId ) + { + TInt parent( KErrNotFound ); + parent = FindParentWgId( aWgId ); + if( parent != KErrNotFound) + { + TInt topParent = FindMostTopParentWgId(parent); + if( topParent != KErrNotFound ) + { + parent = topParent; + } + } + return parent; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::FindAppNameLC +// -------------------------------------------------------------------------- +// +HBufC* CTsFswDataList::FindAppNameLC( CApaWindowGroupName* aWindowName, + const TUid& aAppUid, + TInt aWgId ) + { + //Retrieve the app name + TApaAppInfo info; + iAppArcSession.GetAppInfo( info, aAppUid ); + TPtrC caption = info.iShortCaption; + + HBufC* tempName = 0; + if ( !caption.Length() && aWindowName ) // if not set - use thread name instead + { + if ( aWindowName->Caption().Length() ) + { + tempName = aWindowName->Caption().AllocL(); + //put on cleanupstack after the if + } + else + { + TThreadId threadId; + TInt err = iWsSession.GetWindowGroupClientThreadId( + aWgId, threadId ); + if ( err == KErrNone ) + { + RThread thread; + CleanupClosePushL( thread ); + err = thread.Open ( threadId ); + if ( err==KErrNone ) + { + tempName = thread.Name().AllocL(); // codescanner::forgottoputptroncleanupstack + // tempName put on cleanupstack after the if + } + CleanupStack::PopAndDestroy( &thread ); + } + } + } + else + { + tempName = caption.AllocL(); + //put on cleanupstack after the if + } + CleanupStack::PushL( tempName ); + return tempName; + } + + +// -------------------------------------------------------------------------- +// CTsFswDataList::FitDataToListL +// -------------------------------------------------------------------------- +// +TBool CTsFswDataList::FitDataToListL(RTsFswArray& aListToFit, + TBool /*aConsiderWidgets*/) + { + TBool changed = EFalse; + TInt listCount = aListToFit.Count(); + TInt dataCount = iData.Count(); + + + //remove items that dont't exists in newly collected list + for (TInt i = dataCount -1; i >= 0; --i) + { + if ( !CheckIfExists(*iData[i], aListToFit) ) + { + delete iData[i]; + iData.Remove(i); + changed = ETrue; + } + } + + //add new item at start + //for (TInt i = 0; i < aListToFit.Count(); ++i) + for (TInt i = aListToFit.Count()-1; i >= 0; --i) + { + if (!CheckIfExists(*aListToFit[i], iData)) + { + iData.Insert(aListToFit[i], 0); + aListToFit[i] = 0; + changed = ETrue; + } + } + changed = changed || iOrderChanged; + iOrderChanged = EFalse; + return changed; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::CheckIfExists +// -------------------------------------------------------------------------- +// +TBool CTsFswDataList::CheckIfExists(const CTsFswEntry& aEntry, + const RTsFswArray& aList) const + { + TBool exists(EFalse); + TInt dataCount = aList.Count(); + for (TInt entryIdx = 0; entryIdx < dataCount; ++entryIdx) + { + if (aList[entryIdx]->AppUid() == aEntry.AppUid()) + { + exists = ETrue; + break; + } + } + return exists; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::AppUidForWgId +// -------------------------------------------------------------------------- +// +TInt CTsFswDataList::AppUidForWgId( TInt aWgId, TUid& aUid ) + { + TRAPD(err, aUid = AppUidForWgIdL( aWgId ) ); + return err; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::AppUidForWgIdL +// -------------------------------------------------------------------------- +// +TUid CTsFswDataList::AppUidForWgIdL( TInt aWgId ) + { + CApaWindowGroupName* windowName = + CApaWindowGroupName::NewLC( iWsSession, aWgId ); + TUid appUid = windowName->AppUid(); + CleanupStack::PopAndDestroy( windowName ); + return appUid; + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::GetAppIconL +// -------------------------------------------------------------------------- +// +void CTsFswDataList::GetAppIconL( const TUid& aAppUid, + CFbsBitmap*& aBitmap, CFbsBitmap*& aMask ) + { + aBitmap = aMask = NULL; + + TSize size( KAppIconWidth, KAppIconHeight ); + CApaMaskedBitmap* apaMaskedBitmap = CApaMaskedBitmap::NewLC(); + TInt err = iAppArcSession.GetAppIcon( aAppUid, size, *apaMaskedBitmap ); + TInt iconsCount(0); + if ( err == KErrNone ) + { + err = iAppArcSession.NumberOfOwnDefinedIcons(aAppUid, iconsCount); + } + + if ( (err == KErrNone) && (iconsCount>0) ) + { + aBitmap = static_cast(apaMaskedBitmap); + TInt maskHandle = apaMaskedBitmap->Mask()->Handle(); + aMask = new (ELeave) CFbsBitmap; + aMask->Duplicate( maskHandle ); + CleanupStack::Pop( apaMaskedBitmap ); + } + else + { + CleanupStack::PopAndDestroy( apaMaskedBitmap ); + HBufC* fileNameFromApparc = NULL; + TInt err = iAppArcSession.GetAppIcon(aAppUid,fileNameFromApparc); + if ( err == KErrNone ) + { + CleanupStack::PushL(fileNameFromApparc); + CFbsBitmap *bitamp(0); + CFbsBitmap *mask(0); + TInt bitmapIndex = 0; + TInt maskIndex = 1; + // it will change bitmap ids if it is mif (checking inside) + AknIconUtils::ValidateLogicalAppIconId( *fileNameFromApparc, bitmapIndex, maskIndex ); + AknIconUtils::CreateIconLC( bitamp, mask, fileNameFromApparc->Des(), bitmapIndex, maskIndex ); + + if (AknIconUtils::IsMifFile(*fileNameFromApparc)) \ + { + AknIconUtils::DisableCompression(bitamp); + AknIconUtils::SetSize(bitamp, TSize(KAppIconWidth, KAppIconHeight), EAspectRatioPreservedAndUnusedSpaceRemoved); + // bitmap and icon, AknsUtils::CreateIconLC doesn't specify the order + CleanupStack::Pop(2); + aBitmap = bitamp; + aMask = mask; + } + else + { + CleanupStack::PopAndDestroy(2); + } + CleanupStack::PopAndDestroy(fileNameFromApparc); + } + } + } + +// -------------------------------------------------------------------------- +// CTsFswDataList::GetAppIconL +// -------------------------------------------------------------------------- +// +TBool CTsFswDataList::IsHiddenUid( TUid aUid ) + { + TInt result = iHiddenUids.Find( aUid ); + return result >= 0 ? ETrue : EFalse; + } + +// end of file