--- a/taskswitcher/contextengine/hgfswserver/engine/src/hgfswengine.cpp Fri Jan 22 09:35:14 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1062 +0,0 @@
-/*
- * ===========================================================================
- * Name : hgfswengine.cpp
- * Part of : Huriganes / Fast Swap Server
- * Description : Task monitor engine
- * Version : %version: sa1spcx1#37 %
- *
- * Copyright © 2008 Nokia Corporation.
- * This material, including documentation and any related
- * computer programs, is protected by copyright controlled by
- * Nokia Corporation. All rights are reserved. Copying,
- * including reproducing, storing, adapting or translating, any
- * or all of this material requires the prior written consent of
- * Nokia Corporation. This material also contains confidential
- * information which may not be disclosed to others without the
- * prior written consent of Nokia Corporation.
- * ===========================================================================
- */
-
-#include "hgfswengine.h"
-#include "hgfsalwaysshownapplist.h"
-#include "hgfshiddenapplist.h"
-#include "hgfswidgetlist.h"
-#include "hgfswiconcache.h"
-#include "hgpreviewprovider.h"
-#include "hgfswclient.h"
-#include <apgtask.h>
-#include <AknDef.h>
-#include <apgwgnam.h>
-#include <mmf/common/mmfcontrollerpluginresolver.h> // for CleanupResetAndDestroyPushL
-#include <featmgr.h>
-#include <swi/swispubsubdefs.h>
-
-#include "enginelogging.h"
-
-// time to wait before refreshing content
-const TInt KContentRefreshDelay = 500000; // 0.5 sec
-
-// for screenshots, they are scaled down to (screensize/this_factor).
-const TInt KScreenSizeFactor = 2;
-
-// format to get a lowercase hex string prefixed with 0x
-_LIT( KHexFmt, "0x%x" );
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::NewL
-// --------------------------------------------------------------------------
-//
-EXPORT_C CHgFswEngine* CHgFswEngine::NewL( MHgFswEngineObserver& aObserver )
- {
- CHgFswEngine* self = NewLC( aObserver );
- CleanupStack::Pop( self );
- return self;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::NewLC
-// --------------------------------------------------------------------------
-//
-EXPORT_C CHgFswEngine* CHgFswEngine::NewLC( MHgFswEngineObserver& aObserver )
- {
- CHgFswEngine* self = new ( ELeave ) CHgFswEngine( aObserver );
- CleanupStack::PushL( self );
- self->ConstructL();
- return self;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::CHgFswEngine
-// --------------------------------------------------------------------------
-//
-CHgFswEngine::CHgFswEngine( MHgFswEngineObserver& aObserver )
- : CActive( EPriorityStandard ), iObserver( aObserver )
- {
- CActiveScheduler::Add( this );
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::ConstructL
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::ConstructL()
- {
- iEnv = CEikonEnv::Static();
-
- User::LeaveIfError( iWsSession.Connect() );
- User::LeaveIfError( iAppArcSession.Connect() );
-
- iHiddenAppList = CHgFsHiddenAppList::NewL( *this );
- iAlwaysShownAppList = CHgFsAlwaysShownAppList::NewL();
-
- iWidgetsSupported = FeatureManager::FeatureSupported( KFeatureIdWebWidgets );
- if ( iWidgetsSupported )
- {
- iWidgetList = CHgFsWidgetList::NewL();
- }
-
- // create app icon retriever instance
- iAppIcons = CHgFswIconCache::NewL();
-
- // get an initial list of tasks
- iAppDataRefreshNeeded = ETrue;
- CollectTasksL();
-
- // listen for app screenshots
- iPreviewProvider = CHgFastSwapPreviewProvider::NewL( *this );
- SetPreviewParams();
- UpdatePreviewContent();
-
- iUpdateStarter = CPeriodic::NewL( CActive::EPriorityStandard );
-
- // start listening for swi ps property
- if ( iSwiProp.Attach( KUidSystemCategory,
- Swi::KUidSoftwareInstallKey ) == KErrNone )
- {
- iSwiProp.Subscribe( iStatus );
- SetActive();
- }
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::~CHgFswEngine
-// --------------------------------------------------------------------------
-//
-CHgFswEngine::~CHgFswEngine()
- {
- Cancel();
- iSwiProp.Close();
-
- delete iUpdateStarter;
- delete iPreviewProvider;
-
- // delete the bitmaps as the hash map cannot do that
- THashMapIter<TInt, CFbsBitmap*> iter( iScreenshots );
- while ( const TInt* key = iter.NextKey() )
- {
- CFbsBitmap** value = iter.CurrentValue();
- delete *value;
- }
- iScreenshots.Close();
- delete iAppIcons;
-
- iData.ResetAndDestroy();
- iWgIds.Close();
-
- delete iHiddenAppList;
- delete iAlwaysShownAppList;
- delete iWidgetList;
- iAppArcSession.Close();
- iWsSession.Close();
-
-// delete iContextUtility;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::FswDataL
-// --------------------------------------------------------------------------
-//
-EXPORT_C const RHgFswArray& CHgFswEngine::FswDataL()
- {
- HGLOG_CONTEXT( FswDataL, HGLOG_LOCAL );
- HGLOG1_IN( "dirty flag = %d", iTaskListDirty );
-
- // check the dirty flag and refresh if needed
- if ( iTaskListDirty )
- {
- CollectTasksL();
- // dirty flag is cleared in the above call
- }
-
- // Get app icon for entries without screenshot,
- // do this only here as the app icon is not needed in case a screenshot
- // is already available.
- for ( TInt i = 0, ie = iData.Count(); i != ie; ++i )
- {
- if ( !iData[i]->ScreenshotHandle() )
- {
- CFbsBitmap* bmp;
- CFbsBitmap* mask;
- TUid appUid = iData[i]->AppUid();
- // this will leave with -46 in case of widgets if we do not have AllFiles cap
- TRAPD( err, iAppIcons->GetIconL( appUid, bmp, mask ) );
- if ( err == KErrNone && bmp )
- {
- iData[i]->SetAppIconHandles( bmp->Handle(),
- mask ? mask->Handle() : 0 );
- }
- else
- {
- iAppIcons->DefaultIcon( bmp, mask );
- iData[i]->SetAppIconHandles( bmp->Handle(),
- mask ? mask->Handle() : 0 );
- }
- }
- }
-
- HGLOG_OUT();
- return iData;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::CloseAppL
-// --------------------------------------------------------------------------
-//
-EXPORT_C void CHgFswEngine::CloseAppL( TInt aWgId )
- {
- HGLOG_CONTEXT( CloseAppL, HGLOG_LOCAL );
- HGLOG1_IN( "aWgId = %d", aWgId );
-
- if ( iWidgetsSupported && aWgId < 0 && iWidgetAppUiWgId )
- {
- // for widgets clients see a wgid that is -1*(index+1)
- const RWidgetInfoArray& arr( iWidgetList->RunningWidgets() );
- // convert aWgId to an index in the list of running widgets
- TInt idx = -aWgId - 1;
- // if index is valid then handle the widget specially
- if ( idx >= 0 && idx < arr.Count() )
- {
- TWsEvent event;
- event.SetType( EEventUser );
- TUint8* eventData = event.EventData();
- // Fill bits 0-31 with widget application uid.
- reinterpret_cast<TUint32&>( *eventData ) = KWidgetAppUidValue;
- eventData += sizeof( TUint32 );
- // Fill bits 32-63 with uid of the widget that should be closed.
- reinterpret_cast<TUint32&>( *eventData ) = arr[idx]->iUid.iUid;
- // Send the event to Widget AppUi.
- iEnv->WsSession().SendEventToWindowGroup(
- iWidgetAppUiWgId, event );
- // closing a widget may not cause a window group change so trigger
- // the update manually
- UpdateTaskList();
- HGLOG0_OUT( "widget processing finished" );
- return;
- }
- }
-
- TUid appUid = AppUidForWgIdL( aWgId );
- if ( !iAlwaysShownAppList->IsAlwaysShownApp( appUid ) )
- {
- // send window group event to kill the app
- TWsEvent event;
- event.SetTimeNow();
- event.SetType( KAknShutOrHideApp );
- iEnv->WsSession().SendEventToWindowGroup( aWgId, event );
- HGLOG0( HGLOG_INFO, "event sent to wg" );
- }
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::SwitchToAppL
-// --------------------------------------------------------------------------
-//
-EXPORT_C void CHgFswEngine::SwitchToAppL( TInt aWgId )
- {
- HGLOG_CONTEXT( SwitchToAppL, HGLOG_LOCAL );
- HGLOG1_IN( "aWgId = %d", aWgId );
-
- if ( iWidgetsSupported && aWgId < 0 )
- {
- // for widgets clients see a wgid that is -1*(index+1)
- const RWidgetInfoArray& arr( iWidgetList->RunningWidgets() );
- // convert aWgId to an index in the list of running widgets
- TInt idx = -aWgId - 1;
- // if index is valid then handle the widget specially
- if ( idx >= 0 && idx < arr.Count() )
- {
- SwitchToWidgetL( idx );
- HGLOG1_OUT( "switched to widget %d", idx );
- return;
- }
- }
-
- TApaTask task( iEnv->WsSession() );
- task.SetWgId( aWgId );
- task.BringToForeground();
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::SwitchToWidgetL
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::SwitchToWidgetL( TInt aWidgetIndex )
- {
- const RWidgetInfoArray& arr( iWidgetList->RunningWidgets() );
- RApaLsSession ls;
- User::LeaveIfError( ls.Connect() );
- CleanupClosePushL( ls );
- CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
- cmdLine->SetCommandL( EApaCommandRun );
- TApaAppInfo info;
- iAppArcSession.GetAppInfo( info, arr[aWidgetIndex]->iUid ); // codescanner::accessArrayElementWithoutCheck2 (aWidgetIndex checked in SwitchToAppL())
- cmdLine->SetExecutableNameL( info.iFullName );
- ls.StartApp( *cmdLine );
- CleanupStack::PopAndDestroy( 2, &ls );
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::UpdateTaskList
-// Callback from appui
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::UpdateTaskList()
- {
- HGLOG_CONTEXT( UpdateTaskList, HGLOG_LOCAL );
- HGLOG_IN();
-
- // If no clients are subscribed for fsw content change notifications
- // then there is no need to waste time with rebuilding the task list,
- // just set the dirty flag.
- TInt listenerCount = iObserver.FswDataListenerCount();
- HGLOG1( HGLOG_INFO, "listener count = %d", listenerCount );
- if ( listenerCount > 0 )
- {
- // There can be many calls in a row, use a timer to prevent degrading
- // device performance.
- if ( !iUpdateStarter->IsActive() )
- {
- iUpdateStarter->Start( KContentRefreshDelay, 0,
- TCallBack( UpdateStarterCallback, this ) );
- }
- }
- else
- {
- iTaskListDirty = ETrue;
- }
-
- // screenshot taking support - call Register and Unregister when needed
- UpdatePreviewContent();
-
- // get the foreground app uid and publish it to CFW if different than before
- TRAP_IGNORE( PublishFgAppUidL() );
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::ForegroundAppUidL
-// --------------------------------------------------------------------------
-//
-EXPORT_C TUid CHgFswEngine::ForegroundAppUidL( TInt aType )
- {
- // Do not use GetFocusWindowGroup or others.
- // We want to see only "real" application uids in FgApp,
- // i.e. stuff that would also be shown in the task swapper
- // area of Teleport.
-
- TUid result = KNullUid;
- RArray<RWsSession::TWindowGroupChainInfo> allWgIds;
- CleanupClosePushL( allWgIds );
- User::LeaveIfError( iWsSession.WindowGroupList( 0, &allWgIds ) );
- TInt count = allWgIds.Count();
- for ( TInt i = 0; i < count; ++i )
- {
- // Depending on aType we may not need to bother with iParentId here.
- // If aType == EUseEmbeddedUid => embedded apps are treated as others.
- // If aType == EUseStandaloneUid => embedded apps must be ignored.
- if ( allWgIds[i].iParentId > 0
- && aType == CHgFswClient::EUseStandaloneUid )
- {
- continue;
- }
-
- CApaWindowGroupName* wgn = CApaWindowGroupName::NewLC(
- iWsSession, allWgIds[i].iId );
- TUid newUid = wgn->AppUid();
- TBool hidden = wgn->Hidden() || iHiddenAppList->IsHiddenL(
- newUid, iWsSession, allWgIds[i].iId );
- CleanupStack::PopAndDestroy( wgn );
-
- if ( !hidden && newUid.iUid )
- {
- result = newUid;
- break;
- }
- }
- CleanupStack::PopAndDestroy( &allWgIds );
-
- return result;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::PublishFgAppUidL
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::PublishFgAppUidL()
- {
- HGLOG_CONTEXT( PublishFgAppUidL, HGLOG_LOCAL );
- HGLOG_IN();
-
- TUid newUid = ForegroundAppUidL( CHgFswClient::EUseEmbeddedUid );
- HGLOG2( HGLOG_INFO, "ws says: %x we have: %x", newUid.iUid, iFgAppUid.iUid );
- if ( iFgAppUid != newUid && newUid.iUid )
- {
- iFgAppUid = newUid;
- iFgAppUidStr.Format( KHexFmt, iFgAppUid.iUid );
- //PublishContextL( KHgCFTypeFgApp, iFgAppUidStr );
- }
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::PublishContextL
-// --------------------------------------------------------------------------
-//
-//void CHgFswEngine::PublishContextL( const TDesC& aType, const TDesC& aValue )
-// {
-// HGLOG_CONTEXT( PublishContextL, HGLOG_LOCAL );
-// HGLOG2_IN( "%S: %S", &aType, &aValue );
-// if ( !iContextUtility )
-// {
-// iContextUtility = CHgContextUtility::NewL();
-// iContextUtility->AllowPublishFromBackground( ETrue );
-// }
-// iContextUtility->PublishContextL( aType, aValue );
-// HGLOG_OUT();
-// }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::UpdateStarterCallback
-// Callback for the timer
-// --------------------------------------------------------------------------
-//
-TInt CHgFswEngine::UpdateStarterCallback( TAny* aParam )
- {
- CHgFswEngine* self = static_cast<CHgFswEngine*>( aParam );
- self->iUpdateStarter->Cancel();
- // get list of tasks and notify observer if there is a change in the list
- TBool changed = EFalse;
- TRAPD( err, changed = self->CollectTasksL() );
- if ( err == KErrNone && changed )
- {
- self->iObserver.FswDataChanged();
- }
- return 0;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::CollectTasksL
-// --------------------------------------------------------------------------
-//
-TBool CHgFswEngine::CollectTasksL()
- {
- HGLOG_CONTEXT( CollectTasksL, HGLOG_LOCAL );
- HGLOG_IN();
-
- // clear dirty flag
- iTaskListDirty = EFalse;
-
- TBool changed = EFalse;
- RHgFswArray newList;
- CleanupResetAndDestroyPushL( newList );
-
- // update app data if needed
- // (usually on startup and when new apps might have been installed)
- if ( iAppDataRefreshNeeded )
- {
- HGLOG0( HGLOG_INFO, "refreshing app data" );
- iAppArcSession.GetAllApps();
- iAlwaysShownAppList->InitializeAlwaysShownListL();
- 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;
- }
-
- // will append the task to our own list only if it is not hidden
- TBool onHiddenList = iHiddenAppList->IsHiddenL(
- appUid, iWsSession, wgId );
-
- // if this is the widget app then save wgid for later use
- // and ignore it, but include running widgets instead
- if ( iWidgetsSupported && appUid.iUid == KWidgetAppUidValue )
- {
- iWidgetAppUiWgId = wgId;
- onHiddenList = ETrue;
- CheckWidgetsL( newList );
- }
-
- // get screen number (-1=console, 0=main screen, 1=cover ui)
- TInt appScreen = 0;
- TInt scrNumErr = iAppArcSession.GetDefaultScreenNumber( appScreen, appUid );
-
- // check if it is on always-shown list
- TBool mustShow = iAlwaysShownAppList->IsAlwaysShownApp( appUid );
-
-#ifdef _DEBUG
- const TDesC& captionDbg( windowName->Caption() );
- HGLOG4( HGLOG_INFO, "[%d] wgid=%d appuid=%x (%S)", i, wgId,
- appUid.iUid, &captionDbg );
- HGLOG4( HGLOG_INFO, "hidden=%d onhiddenlist=%d mustshow=%d scrno=%d",
- windowName->Hidden(), onHiddenList, mustShow, appScreen );
-#endif
-
- // add item to task list if it is always-shown OR it is not hidden
- // and it is not on cover ui
- if ( mustShow
- || ( !onHiddenList
- && !windowName->Hidden()
- && ( appScreen == 0 || appScreen == -1 )
- && scrNumErr == KErrNone ) )
- {
- if ( AddEntryL( wgId, appUid, windowName, newList, EFalse ) )
- {
- changed = ETrue;
- }
- }
- CleanupStack::PopAndDestroy( windowName );
- }
- CleanupStack::PopAndDestroy( &allWgIds );
-
- // if counts for old and new lists do not match then there is a change for sure,
- // probably an app has been closed
- if ( iData.Count() != newList.Count() )
- {
- changed = ETrue;
- }
-
- // move pointers from the temporary list into the real one
- iData.ResetAndDestroy();
- TInt newListCount = newList.Count();
- HGLOG1( HGLOG_INFO, "new list count = %d", newListCount );
- for ( TInt i = 0; i < newListCount; ++i )
- {
- HGLOG3( HGLOG_INFO, "[%d] %S wgid=%d",
- i, &newList[i]->AppName(), newList[i]->WgId() );
- iData.AppendL( newList[i] );
- newList[i] = 0;
- }
- CleanupStack::PopAndDestroy( &newList );
-
- HGLOG1_OUT( "change flag = %d", changed );
- return changed;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::AddEntryL
-// --------------------------------------------------------------------------
-//
-TBool CHgFswEngine::AddEntryL( TInt aWgId, const TUid& aAppUid,
- CApaWindowGroupName* aWgName, RHgFswArray& aNewList,
- TBool aIsWidget )
- {
- TBool changed = EFalse;
- CHgFswEntry* entry = CHgFswEntry::NewLC();
- entry->SetWgId( aWgId );
- entry->SetAppUid( aAppUid );
- entry->SetWidget( aIsWidget );
-
- // check if present in old list and if yes then take some of the old data
- TBool found = CheckIfExistsL( *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 );
- TInt h = LookupScreenshotHandle( aWgId );
- if ( h )
- {
- entry->SetScreenshotHandle( h );
- }
- entry->SetAlwaysShown( iAlwaysShownAppList->IsAlwaysShownApp( aAppUid ) );
- if ( aWgName )
- {
- entry->SetSystemApp( aWgName->IsSystem() );
- }
- }
-
- // add to new list, ownership is transferred
- aNewList.AppendL( entry );
- CleanupStack::Pop( entry );
- return changed;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::CheckIfExistsL
-// --------------------------------------------------------------------------
-//
-TBool CHgFswEngine::CheckIfExistsL( CHgFswEntry& aEntry,
- const TUid& aAppUid,
- TBool& aChanged,
- RHgFswArray& 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 )
- {
- // if positions do not match then the list is different than before
- if ( entryIdx != aNewList.Count() )
- {
- aChanged = ETrue;
- }
- CHgFswEntry* oldEntry = iData[entryIdx];
- aEntry.SetAppNameL( oldEntry->AppName() );
- aEntry.SetScreenshotHandle( oldEntry->ScreenshotHandle() );
- aEntry.SetAlwaysShown( oldEntry->AlwaysShown() );
- aEntry.SetSystemApp( oldEntry->SystemApp() );
- return ETrue;
- }
- }
- return EFalse;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::CheckWidgetsL
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::CheckWidgetsL( RHgFswArray& aNewList )
- {
- if ( iWidgetsSupported )
- {
- iWidgetList->InitializeWidgetListL();
- const RWidgetInfoArray& arr( iWidgetList->RunningWidgets() );
- for ( TInt i = 0, ie = arr.Count(); i != ie; ++i )
- {
- // wgid will be a special negative value
- // windowgroupname is not needed here so pass NULL
- AddEntryL( -(i+1), arr[i]->iUid, 0, aNewList, ETrue );
- }
- }
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::HiddenAppListUpdated
-// Callback from the hidden app list watcher
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::HiddenAppListUpdated()
- {
- UpdateTaskList();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::AppUidForWgIdL
-// --------------------------------------------------------------------------
-//
-TUid CHgFswEngine::AppUidForWgIdL( TInt aWgId )
- {
- CApaWindowGroupName* windowName =
- CApaWindowGroupName::NewLC( iWsSession, aWgId );
- TUid appUid = windowName->AppUid();
- CleanupStack::PopAndDestroy( windowName );
- return appUid;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::FindParentWgId
-// --------------------------------------------------------------------------
-//
-TInt CHgFswEngine::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 )
- {
- parent = info.iParentId;
- break;
- }
- }
- }
- allWgIds.Close();
- return parent;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::FindAppNameLC
-// --------------------------------------------------------------------------
-//
-HBufC* CHgFswEngine::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;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::CopyBitmapL
-// --------------------------------------------------------------------------
-//
-CFbsBitmap* CHgFswEngine::CopyBitmapL( TInt aFbsHandle, TBool aKeepAspectRatio )
- {
- CFbsBitmap* ret = new (ELeave) CFbsBitmap;
- CleanupStack::PushL( ret );
- CFbsBitmap* bmp = new (ELeave) CFbsBitmap;
- CleanupStack::PushL( bmp );
- User::LeaveIfError( bmp->Duplicate( aFbsHandle ) );
-
- //Make bitmap width and height equal so that it will look better in FSW control.
- TSize size = bmp->SizeInPixels();
-
- if ( !aKeepAspectRatio )
- {
- if ( size.iHeight > size.iWidth )
- {
- size.iHeight = size.iWidth;
- }
- else
- {
- size.iWidth = size.iHeight;
- }
- }
-
- // preserve size and mode
- User::LeaveIfError( ret->Create( size, EColor64K ) );
-
- CFbsBitmapDevice* doubleBufferDev = CFbsBitmapDevice::NewL( ret );
- CleanupStack::PushL( doubleBufferDev );
-
- CFbsBitGc* doubleBufferGc = 0;
- User::LeaveIfError( doubleBufferDev->CreateContext( doubleBufferGc ) );
- CleanupStack::PushL( doubleBufferGc );
-
- // preserve size
- doubleBufferGc->BitBlt( TPoint( 0, 0 ), bmp, TRect(size) );
-
- CleanupStack::PopAndDestroy( doubleBufferGc );
- CleanupStack::PopAndDestroy( doubleBufferDev );
- CleanupStack::PopAndDestroy( bmp );
- CleanupStack::Pop( ret );
-
- return ret;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::UpdatePreviewContent
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::UpdatePreviewContent()
- {
- HGLOG_CONTEXT( UpdatePreviewContent, HGLOG_LOCAL );
- HGLOG_IN();
-
- RArray<RWsSession::TWindowGroupChainInfo> allWgIds;
- if ( iWsSession.WindowGroupList( 0, &allWgIds ) == KErrNone )
- {
- // check window groups that do not exist anymore
- for ( TInt i = 0, ie = iWgIds.Count(); i != ie; ++i )
- {
- TInt wgid = iWgIds[i];
- TBool present = EFalse;
- for ( TInt j = 0, je = allWgIds.Count(); j != je; ++j )
- {
- if ( allWgIds[j].iId == wgid )
- {
- present = ETrue;
- break;
- }
- }
- if ( !present )
- {
- HGLOG1( HGLOG_INFO, "unregister: %d", wgid );
- iPreviewProvider->Unregister( wgid );
- }
- }
- // check topmost window group
- if ( allWgIds.Count() )
- {
- if ( !iWgIds.Count() || allWgIds[0].iId != iWgIds[0] )
- {
- TInt wgid = allWgIds[0].iId;
- HGLOG1( HGLOG_INFO, "registering %d", wgid );
- iPreviewProvider->Register( wgid );
- }
- }
- // store the new list
- iWgIds.Reset();
- for ( TInt i = 0, ie = allWgIds.Count(); i != ie; ++i )
- {
- iWgIds.Append( allWgIds[i].iId );
- }
- }
- allWgIds.Close();
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::HandleFswPpApplicationChange
-// Callback from CHgFastSwapPreviewProvider
-// Note: aWgId is for the window group for which the screenshot is taken,
-// it may not be the same as the application's wgid (in case of embedded apps)
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::HandleFswPpApplicationChange( TInt aWgId, TInt aFbsHandle )
- {
- HGLOG_CONTEXT( HandleFswPpApplicationChange, HGLOG_LOCAL );
- HGLOG2_IN( "aWgId = %d aFbsHandle = %d", aWgId, aFbsHandle );
-
- CFbsBitmap* bmp = 0;
- TRAPD( err, bmp = CopyBitmapL( aFbsHandle, EFalse ) );
- iPreviewProvider->AckPreview(aFbsHandle);
- if ( err == KErrNone )
- {
- CFbsBitmap** oldbmp = iScreenshots.Find( aWgId );
- if ( oldbmp )
- {
- delete *oldbmp;
- }
- if ( iScreenshots.Insert( aWgId, bmp ) != KErrNone )
- {
- delete bmp;
- iScreenshots.Remove( aWgId );
- }
- else
- {
- AssignScreenshotHandle( aWgId, bmp->Handle() );
- }
- }
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::HandleFswPpApplicationUnregistered
-// Callback from CHgFastSwapPreviewProvider
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::HandleFswPpApplicationUnregistered( TInt aWgId )
- {
- HGLOG_CONTEXT( HandleFswPpApplicationUnregistered, HGLOG_LOCAL );
- HGLOG1_IN( "aWgId = %d", aWgId );
-
- CFbsBitmap** bmp = iScreenshots.Find( aWgId );
- if ( bmp )
- {
- delete *bmp;
- iScreenshots.Remove( aWgId );
- AssignScreenshotHandle( aWgId, 0 );
- }
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::AssignScreenshotHandle
-// Called when a screenshot arrives to check if there is a corresponding
-// application in the task list.
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::AssignScreenshotHandle( TInt aWgIdForScreenshot,
- TInt aBitmapHandle )
- {
- TBool changed = EFalse;
- TInt parentWgId = FindParentWgId( aWgIdForScreenshot );
- // now parentWgId is a valid wgid or KErrNotFound (-1)
- for ( TInt i = 0, ie = iData.Count(); i != ie; ++i )
- {
- if ( iData[i]->Widget() )
- {
- // Do not do anything for now => no screenshot for widgets.
- continue;
- }
- TInt appWgId = iData[i]->WgId();
- if ( appWgId == aWgIdForScreenshot || appWgId == parentWgId )
- {
- iData[i]->SetScreenshotHandle( aBitmapHandle );
- changed = ETrue;
- break;
- }
- }
- if ( changed )
- {
- iObserver.FswDataChanged();
- }
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::LookupScreenshotHandle
-// Called to check if there is a screenshot already stored for the given
-// app. (or a screenshot with a wgid for which aWgIdForApp is the parent)
-// --------------------------------------------------------------------------
-//
-TInt CHgFswEngine::LookupScreenshotHandle( TInt aWgIdForApp )
- {
- CFbsBitmap** bmp = iScreenshots.Find( aWgIdForApp );
- if ( bmp )
- {
- // there is a screenshot stored for this wgid
- return (*bmp)->Handle();
- }
- else if ( aWgIdForApp > 0 )
- {
- // must check if there is a screenshot for which aWgIdForApp is the parent
- THashMapIter<TInt, CFbsBitmap*> iter( iScreenshots );
- while ( const TInt* wgid = iter.NextKey() )
- {
- if ( FindParentWgId( *wgid ) == aWgIdForApp )
- {
- CFbsBitmap** bmp = iter.CurrentValue();
- return (*bmp)->Handle();
- }
- }
- }
- else if ( aWgIdForApp < 0 )
- {
- // Must be a widget, wgid is useless in this case.
- // Do not do anything for now => no screenshot for widgets.
- }
- return 0;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::RunL
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::RunL()
- {
- if ( iStatus != KErrCancel ) // when cancelling the subscribe it completes with KErrCancel
- {
- TInt value = 0;
- if ( iSwiProp.Get( value ) == KErrNone )
- {
- TInt operationStatus( value & Swi::KSwisOperationStatusMask );
- // When an (un)installation has finished change the flag to
- // refresh the app list during the next task list update.
- if ( operationStatus == Swi::ESwisStatusSuccess )
- {
- iAppDataRefreshNeeded = ETrue;
- }
- }
- iSwiProp.Subscribe( iStatus );
- SetActive();
- }
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::DoCancel
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::DoCancel()
- {
- iSwiProp.Cancel();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::RunError
-// --------------------------------------------------------------------------
-//
-TInt CHgFswEngine::RunError( TInt /*aError*/ )
- {
- return KErrNone;
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::HandleResourceChange
-// callback from appui's HandleResourceChangeL
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::HandleResourceChange( TInt aType )
- {
- HGLOG_CONTEXT( HandleResourceChange, HGLOG_LOCAL );
- HGLOG_IN();
-
- if ( iPreviewProvider && aType == KEikDynamicLayoutVariantSwitch )
- {
- SetPreviewParams();
- }
-
- HGLOG_OUT();
- }
-
-// --------------------------------------------------------------------------
-// CHgFswEngine::SetPreviewParams
-// --------------------------------------------------------------------------
-//
-void CHgFswEngine::SetPreviewParams()
- {
- TSize screenSize = iEnv->ScreenDevice()->SizeInPixels();
- iPreviewProvider->SetPreviewParam(
- TSize( screenSize.iWidth / KScreenSizeFactor,
- screenSize.iHeight / KScreenSizeFactor ),
- EColor64K ); // displaymode is ignored
- }
-
-
-// end of file