taskswitcher/backstepping/src/tsbackstepping.cpp
changeset 117 c63ee96dbe5f
equal deleted inserted replaced
115:3ab5c078b490 117:c63ee96dbe5f
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "tsbackstepping.h"
       
    19 
       
    20 #include <w32std.h>// key event
       
    21 #include <apgwgnam.h>// for CApaWindowGroupName
       
    22 #include <apgtask.h>
       
    23 #include <coedef.h>
       
    24 #include <e32property.h>
       
    25 
       
    26 #include <homescreendomainpskeys.h>
       
    27 #include <afactivitylauncher.h>
       
    28 
       
    29 #include "tsbacksteppingfilter.h"
       
    30 
       
    31 _LIT(KHsActivactionUri, "appto://20022F35?activityname=HsIdleView&activityinbackground=true");
       
    32 
       
    33 /** 
       
    34  *  CTsBackstepping::NewL
       
    35  *  two phase constructor
       
    36  */
       
    37 CTsBackstepping* CTsBackstepping::NewL(MTsWindowGroupsMonitor &monitor)
       
    38   {
       
    39   CTsBackstepping* self = CTsBackstepping::NewLC(monitor);
       
    40   CleanupStack::Pop(self);
       
    41   return self;
       
    42   }
       
    43 
       
    44 /** 
       
    45  *  CTsBackstepping::NewLC
       
    46  *  two phase constructor
       
    47  */
       
    48 CTsBackstepping* CTsBackstepping::NewLC(MTsWindowGroupsMonitor &monitor)
       
    49 { 
       
    50   CTsBackstepping* self = new (ELeave) CTsBackstepping(monitor);
       
    51   CleanupStack::PushL(self);
       
    52   self->ConstructL();
       
    53   return self;
       
    54 }
       
    55 
       
    56 /** 
       
    57  * CTsBackstepping::CTsBackstepping
       
    58  * constructor
       
    59  */
       
    60 CTsBackstepping::CTsBackstepping(MTsWindowGroupsMonitor &monitor)
       
    61 :
       
    62 CTsWindowGroupsObserver(monitor)
       
    63 {
       
    64 }
       
    65 
       
    66 /** 
       
    67  *  CTsBackstepping::~CTsBackstepping
       
    68  *  deconstructor
       
    69  */
       
    70 CTsBackstepping::~CTsBackstepping()
       
    71 {
       
    72     delete mFilter;
       
    73 }
       
    74 
       
    75 /** 
       
    76  *  CTsBackstepping::ConstructL
       
    77  *  two phase constructor
       
    78  */
       
    79 void CTsBackstepping::ConstructL ()
       
    80 {
       
    81     BaseConstructL();
       
    82     mFilter = CTsBacksteppingFilter::NewL();
       
    83 }
       
    84 
       
    85 /** 
       
    86  * CTsBackstepping::AnalyseWindowStackL
       
    87  * Analyzes window stack and move homescreen to proper position
       
    88  */
       
    89 void CTsBackstepping::HandleWindowGroupChanged(MTsResourceManager &resource, const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups)
       
    90 {
       
    91     TRAP_IGNORE(HandleWindowGroupChangedL(resource, windowGroups));
       
    92 }
       
    93 
       
    94 /** 
       
    95  * CTsBackstepping::AnalyseWindowStackL
       
    96  * Analyzes window stack and move homescreen to proper position
       
    97  */
       
    98 void CTsBackstepping::HandleWindowGroupChangedL(MTsResourceManager &resource,
       
    99                                                 const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups)
       
   100 {  
       
   101     // calculate the desired position of Homescreen
       
   102     const TInt currentHsOffset(homescreenOffsetL(resource, windowGroups));
       
   103     TInt optimalOffset(1);
       
   104     TInt targetHsOffset(currentHsOffset);
       
   105     for (TInt offset(0); offset < currentHsOffset; ++offset) {
       
   106         TUid uid = getUidFromWindowGroupL(resource, windowGroups[offset].iId);
       
   107         if (TUid::Null() != uid) {
       
   108             if (isEmbededApp(windowGroups[offset])) {
       
   109                 targetHsOffset = parentOffsetL(offset, windowGroups) + 1;
       
   110             } else if (!mFilter->isBlocked(uid)) {
       
   111                 if(offset + 1 < currentHsOffset && 
       
   112                         getUidFromWindowGroupL(resource, windowGroups[offset+1].iId) == TUid::Null()) {
       
   113                 ++optimalOffset;
       
   114                 }
       
   115                 targetHsOffset = optimalOffset;
       
   116             }
       
   117             break;
       
   118         } else {
       
   119             ++optimalOffset;
       
   120         }
       
   121     }
       
   122 
       
   123     // change windows order if necessary
       
   124     if (targetHsOffset != currentHsOffset) {
       
   125         const TInt hsWindowGroup(windowGroups[currentHsOffset].iId);
       
   126         resource.WsSession().SetWindowGroupOrdinalPosition(hsWindowGroup, targetHsOffset);
       
   127     }
       
   128     
       
   129     // switch Homescreen to Idle state if Homescreen is not in foreground and is in different state
       
   130     if (targetHsOffset != 0) {
       
   131         TInt hsState(EHomeScreenIdleState);
       
   132         User::LeaveIfError(RProperty::Get(KHsCategoryUid, KHsCategoryStateKey, hsState));
       
   133         if (hsState != EHomeScreenIdleState) {
       
   134             CAfActivityLauncher *activityEnabler = 
       
   135                 CAfActivityLauncher::NewLC(resource.ApaSession(), 
       
   136                                            resource.WsSession());
       
   137             activityEnabler->launchActivityL(KHsActivactionUri);
       
   138             CleanupStack::PopAndDestroy(activityEnabler);
       
   139         }
       
   140     }
       
   141 }
       
   142 
       
   143 /** 
       
   144  * CTsBackstepping::homescreenOffsetL
       
   145  */
       
   146 TInt CTsBackstepping::homescreenOffsetL(MTsResourceManager &resource,
       
   147                                         const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups) const 
       
   148 {
       
   149     TInt offset(KErrNotFound);
       
   150     for (TInt iter(0);KErrNotFound == offset && iter < windowGroups.Count(); ++iter) {
       
   151         if (KHsCategoryUid == getUidFromWindowGroupL(resource, windowGroups[iter].iId)) {
       
   152             offset = iter;
       
   153         }
       
   154     }
       
   155     User::LeaveIfError(offset);
       
   156     return offset;
       
   157 }
       
   158 
       
   159 /** 
       
   160  * CTsBackstepping::homescreenOffsetL
       
   161  */
       
   162 TInt CTsBackstepping::parentOffsetL(TInt offset,
       
   163                                     const TArray<RWsSession::TWindowGroupChainInfo> &windowGroups) const 
       
   164 {
       
   165     for(TInt iter(offset + 1); iter < windowGroups.Count(); ++iter) {
       
   166         if(windowGroups[iter].iId == windowGroups[offset].iParentId) {
       
   167             return isEmbededApp(windowGroups[iter]) ? 
       
   168                    parentOffsetL(iter, windowGroups) : iter; 
       
   169         }
       
   170     }
       
   171     User::Leave(KErrNotFound);
       
   172     return KErrNotFound;
       
   173 }
       
   174 
       
   175 /** 
       
   176  * CTsBackstepping::isEmbededApp
       
   177  */
       
   178 TBool CTsBackstepping::isEmbededApp(const RWsSession::TWindowGroupChainInfo &windowGroupInfo) const 
       
   179 {
       
   180     return 0 < windowGroupInfo.iParentId;
       
   181 }
       
   182 
       
   183 /** 
       
   184  * CTsBackstepping::getUidFromWindowGroupL
       
   185  */
       
   186 TUid CTsBackstepping::getUidFromWindowGroupL(MTsResourceManager &resource, TInt windowGroupId) const
       
   187 {
       
   188     TUid retVal(TUid::Null());
       
   189     CApaWindowGroupName *windowGroupName = CApaWindowGroupName::NewLC(resource.WsSession());
       
   190     windowGroupName->ConstructFromWgIdL(windowGroupId);
       
   191     retVal = windowGroupName->AppUid();
       
   192     CleanupStack::PopAndDestroy(windowGroupName);
       
   193     return retVal;
       
   194 }
       
   195 
       
   196 // end of file