--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/taskswitcher/backstepping/src/tsbackstepping.cpp Fri Sep 17 08:32:18 2010 +0300
@@ -0,0 +1,242 @@
+/*
+* Copyright (c) 2009 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:
+*
+*/
+
+#include "tsbackstepping.h"
+
+#include <w32std.h>// key event
+#include <apgwgnam.h>// for CApaWindowGroupName
+#include <apgtask.h>
+#include <coedef.h>
+#include <e32property.h>
+#include <e32debug.h>
+
+#include <homescreendomainpskeys.h>
+#include <afactivitylauncher.h>
+
+#include "tsbacksteppingfilter.h"
+
+_LIT(KHsActivactionUri, "appto://20022F35?activityname=HsIdleView&activityinbackground=true");
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::NewL
+ * two phase constructor
+ */
+CTsBackstepping* CTsBackstepping::NewL( MTsWindowGroupsMonitor& aMonitor )
+ {
+ CTsBackstepping* self = CTsBackstepping::NewLC( aMonitor );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::NewLC
+ * two phase constructor
+ */
+CTsBackstepping* CTsBackstepping::NewLC( MTsWindowGroupsMonitor& aMonitor )
+ {
+ CTsBackstepping* self = new (ELeave) CTsBackstepping( aMonitor );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::CTsBackstepping
+ * constructor
+ */
+CTsBackstepping::CTsBackstepping( MTsWindowGroupsMonitor &aMonitor )
+:
+CTsWindowGroupsObserver( aMonitor )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::~CTsBackstepping
+ * deconstructor
+ */
+CTsBackstepping::~CTsBackstepping()
+ {
+ delete iFilter;
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::ConstructL
+ * two phase constructor
+ */
+void CTsBackstepping::ConstructL ()
+ {
+ BaseConstructL();
+ iFilter = CTsBacksteppingFilter::NewL();
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::AnalyseWindowStackL
+ * Analyzes window stack and move homescreen to proper position
+ */
+void CTsBackstepping::HandleWindowGroupChanged(
+ MTsResourceManager &aResource,
+ const TArray<RWsSession::TWindowGroupChainInfo> &aWindowGroups )
+ {
+ RDebug::Print(_L("[Backstepping] started"));
+ TRAP_IGNORE( HandleWindowGroupChangedL( aResource, aWindowGroups ) );
+ RDebug::Print(_L("[Backstepping] finished"));
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::AnalyseWindowStackL
+ * Analyzes window stack and move homescreen to proper position
+ */
+void CTsBackstepping::HandleWindowGroupChangedL(
+ MTsResourceManager& aResource,
+ const TArray<RWsSession::TWindowGroupChainInfo>& aWindowGroups )
+ {
+ // calculate the desired position of Homescreen
+ const TInt currentHsOffset( HomescreenOffsetL( aResource, aWindowGroups ) );
+ TInt optimalOffset(1);
+ TInt targetHsOffset(currentHsOffset);
+ for( TInt offset(0); offset < currentHsOffset; ++offset )
+ {
+ TUid uid = GetUidFromWindowGroupL( aResource,
+ aWindowGroups[offset].iId );
+ RDebug::Print(_L("[Backstepping] application: %d"), uid.iUid);
+
+ if( TUid::Null() != uid )
+ {
+ if( IsEmbededApp( aWindowGroups[offset] ) )
+ {
+ targetHsOffset = ParentOffsetL( offset, aWindowGroups ) + 1;
+ }
+ else if (!iFilter->isBlocked(uid))
+ {
+ if(offset + 1 < currentHsOffset &&
+ GetUidFromWindowGroupL( aResource, aWindowGroups[offset+1].iId) == TUid::Null() )
+ {
+ ++optimalOffset;
+ }
+ targetHsOffset = optimalOffset;
+ }
+ break;
+ }
+ else
+ {
+ ++optimalOffset;
+ }
+ }
+
+ // switch Homescreen to Idle state if Homescreen is not in foreground and is in different state
+ if( 0 != targetHsOffset)
+ {
+ TInt hsState( EHomeScreenIdleState );
+ User::LeaveIfError(RProperty::Get( KHsCategoryUid,
+ KHsCategoryStateKey,
+ hsState ) );
+ if(!(hsState & EHomeScreenWidgetViewActive ) )
+ {
+ RDebug::Print(_L("[Backstepping] about to switch HS activity"));
+
+ CAfActivityLauncher *activityEnabler =
+ CAfActivityLauncher::NewLC( aResource.ApaSession(),
+ aResource.WsSession() );
+ activityEnabler->launchActivityL( KHsActivactionUri );
+ CleanupStack::PopAndDestroy( activityEnabler );
+ }
+ }
+ // change windows order if necessary
+ if(targetHsOffset != currentHsOffset)
+ {
+ RDebug::Print(_L("[Backstepping] about to change window groups order"));
+
+ const TInt hsWindowGroup( aWindowGroups[currentHsOffset].iId );
+ aResource.WsSession().SetWindowGroupOrdinalPosition( hsWindowGroup,
+ targetHsOffset );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::HomescreenOffsetL
+ */
+TInt CTsBackstepping::HomescreenOffsetL(
+ MTsResourceManager& aResource,
+ const TArray<RWsSession::TWindowGroupChainInfo>& aWindowGroups ) const
+ {
+ TInt offset( KErrNotFound );
+ for( TInt iter(0); KErrNotFound == offset && iter < aWindowGroups.Count(); ++iter )
+ {
+ if( KHsCategoryUid == GetUidFromWindowGroupL( aResource, aWindowGroups[iter].iId ) )
+ {
+ offset = iter;
+ }
+ }
+ User::LeaveIfError( offset );
+ return offset;
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::ParentOffsetL
+ */
+TInt CTsBackstepping::ParentOffsetL(
+ TInt aOffset,
+ const TArray<RWsSession::TWindowGroupChainInfo>& aWindowGroups )const
+ {
+ for( TInt iter(aOffset + 1); iter < aWindowGroups.Count(); ++iter )
+ {
+ if(aWindowGroups[iter].iId == aWindowGroups[aOffset].iParentId)
+ {
+ return IsEmbededApp( aWindowGroups[iter] ) ?
+ ParentOffsetL( iter, aWindowGroups ) : iter;
+ }
+ }
+ User::Leave( KErrNotFound) ;
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::IsEmbededApp
+ */
+TBool CTsBackstepping::IsEmbededApp(
+ const RWsSession::TWindowGroupChainInfo &aWindowGroupInfo ) const
+ {
+ return 0 < aWindowGroupInfo.iParentId;
+ }
+
+// -----------------------------------------------------------------------------
+/**
+ * CTsBackstepping::GetUidFromWindowGroupL
+ */
+TUid CTsBackstepping::GetUidFromWindowGroupL( MTsResourceManager &aResource,
+ TInt aWindowGroupId ) const
+ {
+ TUid retVal(TUid::Null());
+ CApaWindowGroupName *windowGroupName =
+ CApaWindowGroupName::NewLC( aResource.WsSession() );
+ windowGroupName->ConstructFromWgIdL( aWindowGroupId );
+ retVal = windowGroupName->AppUid();
+ CleanupStack::PopAndDestroy( windowGroupName );
+ return retVal;
+ }
+
+// end of file