--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/taskswitcher/backstepping/src/tsbackstepping.cpp Thu Sep 16 12:11:40 2010 +0100
@@ -0,0 +1,196 @@
+/*
+* 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 <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 &monitor)
+ {
+ CTsBackstepping* self = CTsBackstepping::NewLC(monitor);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+ * CTsBackstepping::NewLC
+ * two phase constructor
+ */
+CTsBackstepping* CTsBackstepping::NewLC(MTsWindowGroupsMonitor &monitor)
+{
+ CTsBackstepping* self = new (ELeave) CTsBackstepping(monitor);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+}
+
+/**
+ * CTsBackstepping::CTsBackstepping
+ * constructor
+ */
+CTsBackstepping::CTsBackstepping(MTsWindowGroupsMonitor &monitor)
+:
+CTsWindowGroupsObserver(monitor)
+{
+}
+
+/**
+ * CTsBackstepping::~CTsBackstepping
+ * deconstructor
+ */
+CTsBackstepping::~CTsBackstepping()
+{
+ delete mFilter;
+}
+
+/**
+ * CTsBackstepping::ConstructL
+ * two phase constructor
+ */
+void CTsBackstepping::ConstructL ()
+{
+ BaseConstructL();
+ mFilter = CTsBacksteppingFilter::NewL();
+}
+
+/**
+ * CTsBackstepping::AnalyseWindowStackL
+ * Analyzes window stack and move homescreen to proper position
+ */
+void CTsBackstepping::HandleWindowGroupChanged(MTsResourceManager &resource, const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups)
+{
+ TRAP_IGNORE(HandleWindowGroupChangedL(resource, windowGroups));
+}
+
+/**
+ * CTsBackstepping::AnalyseWindowStackL
+ * Analyzes window stack and move homescreen to proper position
+ */
+void CTsBackstepping::HandleWindowGroupChangedL(MTsResourceManager &resource,
+ const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups)
+{
+ // calculate the desired position of Homescreen
+ const TInt currentHsOffset(homescreenOffsetL(resource, windowGroups));
+ TInt optimalOffset(1);
+ TInt targetHsOffset(currentHsOffset);
+ for (TInt offset(0); offset < currentHsOffset; ++offset) {
+ TUid uid = getUidFromWindowGroupL(resource, windowGroups[offset].iId);
+ if (TUid::Null() != uid) {
+ if (isEmbededApp(windowGroups[offset])) {
+ targetHsOffset = parentOffsetL(offset, windowGroups) + 1;
+ } else if (!mFilter->isBlocked(uid)) {
+ if(offset + 1 < currentHsOffset &&
+ getUidFromWindowGroupL(resource, windowGroups[offset+1].iId) == TUid::Null()) {
+ ++optimalOffset;
+ }
+ targetHsOffset = optimalOffset;
+ }
+ break;
+ } else {
+ ++optimalOffset;
+ }
+ }
+
+ // change windows order if necessary
+ if (targetHsOffset != currentHsOffset) {
+ const TInt hsWindowGroup(windowGroups[currentHsOffset].iId);
+ resource.WsSession().SetWindowGroupOrdinalPosition(hsWindowGroup, targetHsOffset);
+ }
+
+ // switch Homescreen to Idle state if Homescreen is not in foreground and is in different state
+ if (targetHsOffset != 0) {
+ TInt hsState(EHomeScreenIdleState);
+ User::LeaveIfError(RProperty::Get(KHsCategoryUid, KHsCategoryStateKey, hsState));
+ if (hsState != EHomeScreenIdleState) {
+ CAfActivityLauncher *activityEnabler =
+ CAfActivityLauncher::NewLC(resource.ApaSession(),
+ resource.WsSession());
+ activityEnabler->launchActivityL(KHsActivactionUri);
+ CleanupStack::PopAndDestroy(activityEnabler);
+ }
+ }
+}
+
+/**
+ * CTsBackstepping::homescreenOffsetL
+ */
+TInt CTsBackstepping::homescreenOffsetL(MTsResourceManager &resource,
+ const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups) const
+{
+ TInt offset(KErrNotFound);
+ for (TInt iter(0);KErrNotFound == offset && iter < windowGroups.Count(); ++iter) {
+ if (KHsCategoryUid == getUidFromWindowGroupL(resource, windowGroups[iter].iId)) {
+ offset = iter;
+ }
+ }
+ User::LeaveIfError(offset);
+ return offset;
+}
+
+/**
+ * CTsBackstepping::homescreenOffsetL
+ */
+TInt CTsBackstepping::parentOffsetL(TInt offset,
+ const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups) const
+{
+ for(TInt iter(offset + 1); iter < windowGroups.Count(); ++iter) {
+ if(windowGroups[iter].iId == windowGroups[offset].iParentId) {
+ return isEmbededApp(windowGroups[iter]) ?
+ parentOffsetL(iter, windowGroups) : iter;
+ }
+ }
+ User::Leave(KErrNotFound);
+ return KErrNotFound;
+}
+
+/**
+ * CTsBackstepping::isEmbededApp
+ */
+TBool CTsBackstepping::isEmbededApp(const RWsSession::TWindowGroupChainInfo &windowGroupInfo) const
+{
+ return 0 < windowGroupInfo.iParentId;
+}
+
+/**
+ * CTsBackstepping::getUidFromWindowGroupL
+ */
+TUid CTsBackstepping::getUidFromWindowGroupL(MTsResourceManager &resource, TInt windowGroupId) const
+{
+ TUid retVal(TUid::Null());
+ CApaWindowGroupName *windowGroupName = CApaWindowGroupName::NewLC(resource.WsSession());
+ windowGroupName->ConstructFromWgIdL(windowGroupId);
+ retVal = windowGroupName->AppUid();
+ CleanupStack::PopAndDestroy(windowGroupName);
+ return retVal;
+}
+
+// end of file