tstaskmonitor/server/src/tsfswdatalist.cpp
changeset 80 397d00875918
child 83 156f692b1687
--- /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 <mmf/common/mmfcontrollerpluginresolver.h> // for CleanupResetAndDestroyPushL
+#include <featmgr.h>
+#include <apgwgnam.h>
+#include <AknsUtils.h>
+#include <gulicon.h>
+#include <e32debug.h>
+#include <bitstd.h>
+#include <AknIconUtils.h> // avkon
+#include <APGICNFL.H> // fbsbitmap
+#include <akniconsrvclient.h> 
+
+// 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<RWsSession::TWindowGroupChainInfo> 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<RWsSession::TWindowGroupChainInfo> 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<CFbsBitmap*>(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