--- /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 <apgtask.h>
+#include <AknDef.h>
+#include <apgwgnam.h>
+#include <mmf/common/mmfcontrollerpluginresolver.h> // for CleanupResetAndDestroyPushL
+#include <featmgr.h>
+#include <swi/swispubsubdefs.h>
+#include <s32mem.h>
+#include <bitmaptransforms.h>
+#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<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 == 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<CTsFswEngine*>( 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<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 )
+ {
+ 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