diff -r 5f0182e07bfb -r 5456b4e8b3a8 taskswitcher/contextengine/tsfswserver/engine/src/tsfswengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/taskswitcher/contextengine/tsfswserver/engine/src/tsfswengine.cpp Wed Sep 01 12:32:46 2010 +0100 @@ -0,0 +1,854 @@ +/* +* 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: Task monitor engine + * +*/ + + +#include "tsfswengine.h" +#include "tscpsnotifier.h" +#include "tsfswdatalist.h" +#include "tsfsalwaysshownapplist.h" +#include "tsfshiddenapplist.h" +#include "tsfswidgetlist.h" +#include "tspreviewprovider.h" +#include "tsfswclient.h" +#include +#include +#include +#include // for CleanupResetAndDestroyPushL +#include +#include +#include +#include +#include "enginelogging.h" + +// time to wait before refreshing content +const TInt KContentRefreshDelay = 50000; // 0.05 sec + +// for screenshots, they are scaled down to (screensize/this_factor). +const TInt KScreenSizeFactor = 2; + +const TUid KTsCameraUid = { 0x101F857a }; + +//close command for widget +const TInt KCloseWidgetCmd(9); +//handle close cmd for s60 widgets +_LIT(KWidgetAppName, "widgetlauncher.exe"); +//handle close cmd for CWRT widgets +_LIT(KWidgetAppNameWgt,"wgtwidgetlauncher.exe"); + +// -------------------------------------------------------------------------- +// CTsFswEngine::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CTsFswEngine* CTsFswEngine::NewL( MTsFswEngineObserver& aObserver ) + { + CTsFswEngine* self = NewLC( aObserver ); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::NewLC +// -------------------------------------------------------------------------- +// +EXPORT_C CTsFswEngine* CTsFswEngine::NewLC( MTsFswEngineObserver& aObserver ) + { + CTsFswEngine* self = new ( ELeave ) CTsFswEngine( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::CTsFswEngine +// -------------------------------------------------------------------------- +// +CTsFswEngine::CTsFswEngine( MTsFswEngineObserver& aObserver ) + : CActive( EPriorityStandard ), iObserver( aObserver ) + { + CActiveScheduler::Add( this ); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::ConstructL +// -------------------------------------------------------------------------- +// +void CTsFswEngine::ConstructL() + { + iEnv = CEikonEnv::Static(); + + User::LeaveIfError( iWsSession.Connect() ); + User::LeaveIfError( iAppArcSession.Connect() ); + + iDataList = CTsFswDataList::NewL(*this); + iWidgetsSupported = FeatureManager::FeatureSupported( KFeatureIdWebWidgets ); + + // get an initial list of tasks + iDataList->SetAppDataRefreshNeeded(); + CollectTasksL(); + + // listen for app screenshots + iPreviewProvider = CTsFastSwapPreviewProvider::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(); + } + iCpsWidgetPublisher = CTSCpsNotifier::NewL(*this); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::~CTsFswEngine +// -------------------------------------------------------------------------- +// +CTsFswEngine::~CTsFswEngine() + { + Cancel(); + iSwiProp.Close(); + + delete iUpdateStarter; + delete iPreviewProvider; + + iWgIds.Close(); + + iAppArcSession.Close(); + iWsSession.Close(); + + for ( TInt i = 0; i < iRotaTasks.Count(); i++ ) + { + iRotaTasks[i]->Cancel(); + delete iRotaTasks[i]; + } + iRotaTasks.Close(); + delete iDataList; + delete iCpsWidgetPublisher; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::FswDataL +// -------------------------------------------------------------------------- +// +EXPORT_C const RTsFswArray& CTsFswEngine::FswDataL() + { + TSLOG_CONTEXT( FswDataL, TSLOG_LOCAL ); + TSLOG_OUT(); + return iDataList->FswDataL(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::CloseAppL +// -------------------------------------------------------------------------- +// +EXPORT_C void CTsFswEngine::CloseAppL( TInt aWgId ) + { + TSLOG_CONTEXT( CloseAppL, TSLOG_LOCAL ); + TSLOG1_IN( "aWgId = %d", aWgId ); + + if( iWidgetsSupported && 0 > aWgId ) + { + // convert aWgId to an index in the list of running widgets and close widget + CloseWidgetL( -aWgId -1 ); + } + else if( !iDataList->IsAlwaysShownAppL( aWgId ) ) + { + // send window group event to kill the app + TWsEvent event; + event.SetTimeNow(); + event.SetType( KAknShutOrHideApp ); + iEnv->WsSession().SendEventToWindowGroup( aWgId, event ); + TSLOG0( TSLOG_INFO, "event sent to wg" ); + } + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::SwitchToAppL +// -------------------------------------------------------------------------- +// +EXPORT_C void CTsFswEngine::SwitchToAppL( TInt aWgId ) + { + TSLOG_CONTEXT( SwitchToAppL, TSLOG_LOCAL ); + TSLOG1_IN( "aWgId = %d", aWgId ); + + if ( iWidgetsSupported && aWgId < 0 ) + { + // for widgets clients see a wgid that is -1*(index+1) + const RWidgetInfoArray& arr( iDataList->Widgets()->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 ); + TSLOG1_OUT( "switched to widget %d", idx ); + return; + } + } + + TApaTask task( iEnv->WsSession() ); + task.SetWgId( aWgId ); + task.BringToForeground(); + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::SwitchToWidgetL +// -------------------------------------------------------------------------- +// +void CTsFswEngine::SwitchToWidgetL( TInt aWidgetIndex ) + { + const RWidgetInfoArray& arr( iDataList->Widgets()->RunningWidgets() ); + 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 ); + iAppArcSession.StartApp( *cmdLine ); + CleanupStack::PopAndDestroy(cmdLine); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::UpdateTaskList +// Callback from appui +// -------------------------------------------------------------------------- +// +void CTsFswEngine::UpdateTaskList() + { + TSLOG_CONTEXT( UpdateTaskList, TSLOG_LOCAL ); + TSLOG_IN(); + + // 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() ); + + // 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 ) ); + } + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::ForegroundAppUidL +// -------------------------------------------------------------------------- +// +EXPORT_C TUid CTsFswEngine::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 Taskswitcher. + + TUid result = KNullUid; + RArray 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 == CTsFswClient::EUseStandaloneUid ) + { + continue; + } + + CApaWindowGroupName* wgn = CApaWindowGroupName::NewLC( + iWsSession, allWgIds[i].iId ); + TUid newUid = wgn->AppUid(); + TBool hidden = wgn->Hidden() || iDataList->HiddenApps()->IsHiddenL( + newUid, iWsSession, allWgIds[i].iId ); + CleanupStack::PopAndDestroy( wgn ); + + if ( !hidden && newUid.iUid ) + { + result = newUid; + break; + } + } + CleanupStack::PopAndDestroy( &allWgIds ); + + return result; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::PublishFgAppUidL +// -------------------------------------------------------------------------- +// +void CTsFswEngine::PublishFgAppUidL() + { + TSLOG_CONTEXT( PublishFgAppUidL, TSLOG_LOCAL ); + TSLOG_IN(); + + TUid newUid = ForegroundAppUidL( CTsFswClient::EUseEmbeddedUid ); + TSLOG2( TSLOG_INFO, "ws says: %x we have: %x", newUid.iUid, iFgAppUid.iUid ); + if ( iFgAppUid != newUid && newUid.iUid ) + { + iFgAppUid = newUid; + iDataList->MoveEntryAtStart(newUid.iUid, EFalse); + TBool change( iDataList->MoveEntryAtStart(newUid.iUid, EFalse) ); + if( change ) + { + iObserver.FswDataChanged(); + } + } + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::UpdateStarterCallback +// Callback for the timer +// -------------------------------------------------------------------------- +// +TInt CTsFswEngine::UpdateStarterCallback( TAny* aParam ) + { + CTsFswEngine* self = static_cast( 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; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::CollectTasksL +// -------------------------------------------------------------------------- +// +TBool CTsFswEngine::CollectTasksL() + { + TSLOG_CONTEXT( CollectTasksL, TSLOG_LOCAL ); + TBool changed = iDataList->CollectTasksL(); + TSLOG1_OUT( "change flag = %d", changed ); + return changed; + } + + +// CTsFswEngine::HiddenAppListUpdated +// Callback from the hidden app list watcher +// -------------------------------------------------------------------------- +// +void CTsFswEngine::HiddenAppListUpdated() + { + UpdateTaskList(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::CopyBitmapL +// -------------------------------------------------------------------------- +// +CFbsBitmap* CTsFswEngine::CopyBitmapL( TInt aFbsHandle, TBool aKeepAspectRatio ) + { + TSLOG_CONTEXT( CopyBitmapL, TSLOG_LOCAL ); + + 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 ); + + TSLOG_OUT(); + return ret; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::UpdatePreviewContent +// -------------------------------------------------------------------------- +// +void CTsFswEngine::UpdatePreviewContent() + { + TSLOG_CONTEXT( UpdatePreviewContent, TSLOG_LOCAL ); + TSLOG_IN(); + + RArray 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 ) + { + TSLOG1( TSLOG_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; + TSLOG1( TSLOG_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(); + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::HandleFswPpApplicationChange +// Callback from CTsFastSwapPreviewProvider +// 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 CTsFswEngine::HandleFswPpApplicationChange( TInt aWgId, TInt aFbsHandle ) + { + TSLOG_CONTEXT( HandleFswPpApplicationChange, TSLOG_LOCAL ); + TSLOG2_IN( "aWgId = %d aFbsHandle = %d", aWgId, aFbsHandle ); + + TUid appUid; + TInt wgId = iDataList->FindMostTopParentWgId(aWgId); + if ( wgId == KErrNotFound ) + { + wgId = aWgId; + } + TInt err = iDataList->AppUidForWgId( wgId, appUid ); + if ( err || appUid == KTsCameraUid ) + { + // Dont't assign screenshot to camera app + TSLOG0( TSLOG_LOCAL, "Screenshot for camera - ignore" ); + iPreviewProvider->AckPreview(aFbsHandle); + TSLOG_OUT(); + return; + } + + CFbsBitmap* bmp = 0; + TRAP( err, bmp = CopyBitmapL( aFbsHandle, EFalse ) ); + iPreviewProvider->AckPreview(aFbsHandle); + if ( err == KErrNone ) + { + StoreScreenshot(aWgId, bmp); + } + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::HandleFswPpApplicationUnregistered +// Callback from CTsFastSwapPreviewProvider +// -------------------------------------------------------------------------- +// +void CTsFswEngine::HandleFswPpApplicationUnregistered( TInt aWgId ) + { + TSLOG_CONTEXT( HandleFswPpApplicationUnregistered, TSLOG_LOCAL ); + TSLOG1_IN( "aWgId = %d", aWgId ); + + RemoveScreenshot(aWgId); + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::HandleFswPpApplicationBitmapRotation +// Callback from CTsFastSwapPreviewProvider +// -------------------------------------------------------------------------- +// +void CTsFswEngine::HandleFswPpApplicationBitmapRotation( TInt aWgId, TBool aClockwise ) + { + TSLOG_CONTEXT( HandleFswPpApplicationBitmapRotation, TSLOG_LOCAL ); + TSLOG1_IN( "aWgId = %d", aWgId ); + + CFbsBitmap** bmp = iDataList->FindScreenshot(aWgId); + + if ( bmp ) + { + // Rotate bitmap + TRAP_IGNORE( RotateL( **bmp, aWgId, aClockwise ) ); + // Bitmap in a array is invalid, remove it + RemoveScreenshot(aWgId); + } + + TSLOG_OUT(); + } + + +// -------------------------------------------------------------------------- +// CTsFswEngine::RotateL +// Callback from CTsFastSwapPreviewProvider +// -------------------------------------------------------------------------- +// +void CTsFswEngine::RotateL( CFbsBitmap& aBitmap, TInt aWgId, TBool aClockwise ) + { + CFbsBitmap* rotaBitmap = new (ELeave) CFbsBitmap; + CleanupStack::PushL( rotaBitmap ); + User::LeaveIfError( rotaBitmap->Duplicate( aBitmap.Handle() ) ); + CTsRotationTask* rotaTask = new (ELeave) CTsRotationTask( *this ); + CleanupStack::PushL( rotaTask ); + User::LeaveIfError( iRotaTasks.Append( rotaTask ) ); + rotaTask->StartLD( aWgId, rotaBitmap, aClockwise ); // ownership transferred + CleanupStack::Pop( rotaTask ); + CleanupStack::Pop( rotaBitmap ); + } + + +// -------------------------------------------------------------------------- +// CTsFswEngine::RotationComplete +// Callback from CTsFastSwapPreviewProvider +// -------------------------------------------------------------------------- +// +void CTsFswEngine::RotationComplete( TInt aWgId, + CFbsBitmap* aBitmap, + CTsRotationTask* aCompletedTask, + TInt aError ) + { + TSLOG_CONTEXT( RotationComplete, TSLOG_LOCAL ); + TSLOG_IN(); + + TSLOG1( TSLOG_INFO, "---> rotation completed with status: %d", aError ); + TInt idx = iRotaTasks.Find( aCompletedTask ); + if ( idx != KErrNotFound ) + { + // Update task list + iRotaTasks.Remove(idx); + } + + if ( aError == KErrNone ) + { + StoreScreenshot(aWgId, aBitmap); + } + else + { + // Rotation failed, cleanup bitmap + delete aBitmap; + } + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::RunL +// -------------------------------------------------------------------------- +// +void CTsFswEngine::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 ) + { + iDataList->SetAppDataRefreshNeeded(); + } + } + iSwiProp.Subscribe( iStatus ); + SetActive(); + } + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::DoCancel +// -------------------------------------------------------------------------- +// +void CTsFswEngine::DoCancel() + { + iSwiProp.Cancel(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::RunError +// -------------------------------------------------------------------------- +// +TInt CTsFswEngine::RunError( TInt /*aError*/ ) + { + return KErrNone; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::HandleResourceChange +// callback from appui's HandleResourceChangeL +// -------------------------------------------------------------------------- +// +void CTsFswEngine::HandleResourceChange( TInt aType ) + { + TSLOG_CONTEXT( HandleResourceChange, TSLOG_LOCAL ); + TSLOG_IN(); + + if ( iPreviewProvider && aType == KEikDynamicLayoutVariantSwitch ) + { + SetPreviewParams(); + } + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::SetPreviewParams +// -------------------------------------------------------------------------- +// +void CTsFswEngine::SetPreviewParams() + { + TSize screenSize = iEnv->ScreenDevice()->SizeInPixels(); + iPreviewProvider->SetPreviewParam( + TSize( screenSize.iWidth / KScreenSizeFactor, + screenSize.iHeight / KScreenSizeFactor ), + EColor64K ); // displaymode is ignored + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::CloseWidgetL +// -------------------------------------------------------------------------- +// +void CTsFswEngine::CloseWidgetL(TInt aOffset ) + { + TSLOG_CONTEXT( CloseWidgetL, TSLOG_LOCAL ); + TSLOG1_IN( "aOffset = %d", aOffset ); + if( iDataList->Widgets()->RunningWidgets().Count() <= aOffset ) + { + User::Leave(KErrArgument); + } + const CWidgetInfo* widgetInfo(iDataList->Widgets()->RunningWidgets()[aOffset]); + const TPtrC bundleName(*widgetInfo->iBundleName); + CApaCommandLine* const cmdLine = CApaCommandLine::NewLC(); + + HBufC8* const + opaque( HBufC8::NewLC( bundleName.Size() + 3 * sizeof( TUint32 ) ) ); + TPtr8 des ( opaque->Des() ); + RDesWriteStream stream; + stream.Open( des ); + CleanupClosePushL( stream ); + stream.WriteUint32L ( widgetInfo->iUid.iUid ); + stream.WriteUint32L ( bundleName.Length() ); + stream.WriteL ( reinterpret_cast< const TUint8* >( bundleName.Ptr() ), bundleName.Size()); + stream.WriteInt32L ( KCloseWidgetCmd ); + CleanupStack::PopAndDestroy( &stream ); + cmdLine->SetCommandL( EApaCommandBackgroundAndWithoutViews ); + cmdLine->SetOpaqueDataL( *opaque ); + CleanupStack::PopAndDestroy( opaque ); + + if (iDataList->Widgets()->IsCWRTWidget(widgetInfo->iUid)) + { + cmdLine->SetExecutableNameL( KWidgetAppNameWgt); + } + else + { + cmdLine->SetExecutableNameL( KWidgetAppName ); + } + + iAppArcSession.StartApp( *cmdLine ); + CleanupStack::PopAndDestroy( cmdLine ); + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::StoreScreenshot +// -------------------------------------------------------------------------- +// +TBool CTsFswEngine::StoreScreenshot(TInt aWgId, CFbsBitmap* aBmp) + { + TSLOG_CONTEXT( StoreScreenshot, TSLOG_LOCAL ); + //iDataList would take ownership + TBool change = EFalse; + change = iDataList->StoreScreenshot(aWgId, aBmp); + if(change) + { + iObserver.FswDataChanged(); + } + TSLOG1_OUT( "Screenshot for = %d", aWgId ); + return change; + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::RemoveScreenshot() +// -------------------------------------------------------------------------- +// +void CTsFswEngine::RemoveScreenshot(TInt aWgId) + { + TBool change = EFalse; + change = iDataList->RemoveScreenshot(aWgId); + if( change ) + { + iObserver.FswDataChanged(); + } + } + +// -------------------------------------------------------------------------- +// CTsFswEngine::HandleWidgetUpdateL() +// -------------------------------------------------------------------------- +// +void CTsFswEngine::HandleWidgetUpdateL(TInt aWidgetId, TInt aBitmapHandle) + { + TSLOG_CONTEXT( HandleWidgetUpdateL, TSLOG_LOCAL ); + + TBool contentChanged( iDataList->MoveEntryAtStart(aWidgetId, ETrue) ); + + CFbsBitmap* bmp = 0; + if( aBitmapHandle ) + { + TRAPD( err, bmp = CopyBitmapL( aBitmapHandle, EFalse ) ); + if ( err == KErrNone ) + { + contentChanged = StoreScreenshot(aWidgetId, bmp); + } + } + if(!contentChanged) + { + iObserver.FswDataChanged(); + } + + TSLOG_OUT(); + } + +// -------------------------------------------------------------------------- +// CTsRotationListener::CTsRotationListener +// -------------------------------------------------------------------------- +// +CTsRotationTask::CTsRotationTask(CTsFswEngine& aEngine ) +: CActive(EPriorityStandard), + iEngine(aEngine) + { + CActiveScheduler::Add( this ); + } + + +// -------------------------------------------------------------------------- +// CTsRotationListener::~CTsRotationListener +// -------------------------------------------------------------------------- +// +CTsRotationTask::~CTsRotationTask() + { + Cancel(); + delete iRotator; + delete iBitmap; + } + + +// -------------------------------------------------------------------------- +// CTsRotationListener::Start +// -------------------------------------------------------------------------- +// +void CTsRotationTask::StartLD( TInt aWgId, + CFbsBitmap* aBitmap, + TBool aClockwise ) + { + TSLOG_CONTEXT( StartLD, TSLOG_LOCAL ); + TSLOG_IN(); + + iWgId = aWgId; + iBitmap = aBitmap; + iRotator = CBitmapRotator::NewL(); + if ( aClockwise ) + { + iRotator->Rotate(&iStatus, *iBitmap, CBitmapRotator::ERotation90DegreesClockwise); + } + else + { + iRotator->Rotate(&iStatus, *iBitmap, CBitmapRotator::ERotation270DegreesClockwise); + } + SetActive(); + + TSLOG_OUT(); + } + + +// -------------------------------------------------------------------------- +// CTsRotationListener::RunL +// -------------------------------------------------------------------------- +// +void CTsRotationTask::RunL() + { + iEngine.RotationComplete( iWgId, iBitmap, this, iStatus.Int() ); // bitmap ownership transferred + iBitmap = NULL; + delete this; + } + + +// -------------------------------------------------------------------------- +// CTsRotationListener::DoCancel +// -------------------------------------------------------------------------- +// +void CTsRotationTask::DoCancel() + { + iRotator->Cancel(); + } + +// end of file