diff -r 3ab5c078b490 -r c63ee96dbe5f taskswitcher/backstepping/src/tsbackstepping.cpp --- /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 // key event +#include // for CApaWindowGroupName +#include +#include +#include + +#include +#include + +#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 &windowGroups) +{ + TRAP_IGNORE(HandleWindowGroupChangedL(resource, windowGroups)); +} + +/** + * CTsBackstepping::AnalyseWindowStackL + * Analyzes window stack and move homescreen to proper position + */ +void CTsBackstepping::HandleWindowGroupChangedL(MTsResourceManager &resource, + const TArray &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 &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 &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