tstaskmonitor/server/src/tsfswdatalist.cpp
author hgs
Fri, 14 May 2010 17:24:44 +0300
changeset 94 dbb8300717f7
child 83 156f692b1687
permissions -rw-r--r--
201019

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