taskswitcher/backstepping/src/tsbackstepping.cpp
changeset 116 305818acdca4
child 119 50e220be30d1
equal deleted inserted replaced
112:dbfb5e38438b 116:305818acdca4
       
     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 #include <e32debug.h>
       
    26 
       
    27 #include <homescreendomainpskeys.h>
       
    28 #include <afactivitylauncher.h>
       
    29 
       
    30 #include "tsbacksteppingfilter.h"
       
    31 
       
    32 _LIT(KHsActivactionUri, "appto://20022F35?activityname=HsIdleView&activityinbackground=true");
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 /** 
       
    36  *  CTsBackstepping::NewL
       
    37  *  two phase constructor
       
    38  */
       
    39 CTsBackstepping* CTsBackstepping::NewL( MTsWindowGroupsMonitor& aMonitor )
       
    40     {
       
    41     CTsBackstepping* self = CTsBackstepping::NewLC( aMonitor );
       
    42     CleanupStack::Pop( self );
       
    43     return self;
       
    44     }
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 /** 
       
    48  *  CTsBackstepping::NewLC
       
    49  *  two phase constructor
       
    50  */
       
    51 CTsBackstepping* CTsBackstepping::NewLC( MTsWindowGroupsMonitor& aMonitor )
       
    52     { 
       
    53     CTsBackstepping* self = new (ELeave) CTsBackstepping( aMonitor );
       
    54     CleanupStack::PushL( self );
       
    55     self->ConstructL();
       
    56     return self;
       
    57     }
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 /** 
       
    61  * CTsBackstepping::CTsBackstepping
       
    62  * constructor
       
    63  */
       
    64 CTsBackstepping::CTsBackstepping( MTsWindowGroupsMonitor &aMonitor )
       
    65 :
       
    66 CTsWindowGroupsObserver( aMonitor )
       
    67     {
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 /** 
       
    72  *  CTsBackstepping::~CTsBackstepping
       
    73  *  deconstructor
       
    74  */
       
    75 CTsBackstepping::~CTsBackstepping()
       
    76     {
       
    77     delete iFilter;
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 /** 
       
    82  *  CTsBackstepping::ConstructL
       
    83  *  two phase constructor
       
    84  */
       
    85 void CTsBackstepping::ConstructL ()
       
    86     {
       
    87     BaseConstructL();
       
    88     iFilter = CTsBacksteppingFilter::NewL();
       
    89     }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 /** 
       
    93  * CTsBackstepping::AnalyseWindowStackL
       
    94  * Analyzes window stack and move homescreen to proper position
       
    95  */
       
    96 void CTsBackstepping::HandleWindowGroupChanged( 
       
    97                MTsResourceManager &aResource, 
       
    98                const TArray<RWsSession::TWindowGroupChainInfo> &aWindowGroups )
       
    99     {
       
   100     RDebug::Print(_L("[Backstepping] started"));
       
   101     TRAP_IGNORE( HandleWindowGroupChangedL( aResource, aWindowGroups ) );
       
   102     RDebug::Print(_L("[Backstepping] finished"));
       
   103     }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 /** 
       
   107  * CTsBackstepping::AnalyseWindowStackL
       
   108  * Analyzes window stack and move homescreen to proper position
       
   109  */
       
   110 void CTsBackstepping::HandleWindowGroupChangedL( 
       
   111                 MTsResourceManager& aResource,
       
   112                 const TArray<RWsSession::TWindowGroupChainInfo>& aWindowGroups )
       
   113     {
       
   114     // calculate the desired position of Homescreen
       
   115     const TInt currentHsOffset( HomescreenOffsetL( aResource, aWindowGroups ) );
       
   116     TInt optimalOffset(1);
       
   117     TInt targetHsOffset(currentHsOffset);
       
   118     for( TInt offset(0); offset < currentHsOffset; ++offset ) 
       
   119         {
       
   120         TUid uid = GetUidFromWindowGroupL( aResource, 
       
   121                                            aWindowGroups[offset].iId );
       
   122         RDebug::Print(_L("[Backstepping] application: %d"), uid.iUid);
       
   123                                            
       
   124         if( TUid::Null() != uid )
       
   125             {
       
   126             if( IsEmbededApp( aWindowGroups[offset] ) )
       
   127                 {
       
   128                 targetHsOffset = ParentOffsetL( offset, aWindowGroups ) + 1;
       
   129                 } 
       
   130             else if (!iFilter->isBlocked(uid))
       
   131                 {
       
   132                 if(offset + 1 < currentHsOffset && 
       
   133                    GetUidFromWindowGroupL( aResource, aWindowGroups[offset+1].iId) == TUid::Null() ) 
       
   134                     {
       
   135                     ++optimalOffset;
       
   136                     }
       
   137                 targetHsOffset = optimalOffset;
       
   138                 }
       
   139             break;
       
   140             } 
       
   141         else
       
   142             {
       
   143             ++optimalOffset;
       
   144             }
       
   145         }
       
   146 
       
   147     // switch Homescreen to Idle state if Homescreen is not in foreground and is in different state
       
   148     if( 0 != targetHsOffset)
       
   149         {
       
   150         TInt hsState( EHomeScreenIdleState );
       
   151         User::LeaveIfError(RProperty::Get( KHsCategoryUid, 
       
   152                                            KHsCategoryStateKey, 
       
   153                                            hsState ) );
       
   154         if(!(hsState & EHomeScreenWidgetViewActive ) )
       
   155             {
       
   156             RDebug::Print(_L("[Backstepping] about to switch HS activity"));
       
   157             
       
   158             CAfActivityLauncher *activityEnabler = 
       
   159                 CAfActivityLauncher::NewLC( aResource.ApaSession(), 
       
   160                                             aResource.WsSession() );
       
   161             activityEnabler->launchActivityL( KHsActivactionUri );
       
   162             CleanupStack::PopAndDestroy( activityEnabler );
       
   163             }
       
   164         }
       
   165     // change windows order if necessary
       
   166     if(targetHsOffset != currentHsOffset)
       
   167         {
       
   168         RDebug::Print(_L("[Backstepping] about to change window groups order"));
       
   169         
       
   170         const TInt hsWindowGroup( aWindowGroups[currentHsOffset].iId );
       
   171         aResource.WsSession().SetWindowGroupOrdinalPosition( hsWindowGroup, 
       
   172                                                              targetHsOffset );
       
   173         }
       
   174     }
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 /** 
       
   178  * CTsBackstepping::HomescreenOffsetL
       
   179  */
       
   180 TInt CTsBackstepping::HomescreenOffsetL( 
       
   181         MTsResourceManager& aResource,
       
   182         const TArray<RWsSession::TWindowGroupChainInfo>& aWindowGroups ) const 
       
   183     {
       
   184     TInt offset( KErrNotFound );
       
   185     for( TInt iter(0); KErrNotFound == offset && iter < aWindowGroups.Count(); ++iter )
       
   186         {
       
   187         if( KHsCategoryUid == GetUidFromWindowGroupL( aResource, aWindowGroups[iter].iId ) )
       
   188             {
       
   189             offset = iter;
       
   190             }
       
   191         }
       
   192     User::LeaveIfError( offset );
       
   193     return offset;
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 /** 
       
   198  * CTsBackstepping::ParentOffsetL
       
   199  */
       
   200 TInt CTsBackstepping::ParentOffsetL( 
       
   201         TInt aOffset,
       
   202         const TArray<RWsSession::TWindowGroupChainInfo>& aWindowGroups )const 
       
   203     {
       
   204     for( TInt iter(aOffset + 1); iter < aWindowGroups.Count(); ++iter )
       
   205         {
       
   206         if(aWindowGroups[iter].iId == aWindowGroups[aOffset].iParentId)
       
   207             {
       
   208             return IsEmbededApp( aWindowGroups[iter] ) ? 
       
   209                    ParentOffsetL( iter, aWindowGroups ) : iter; 
       
   210             }
       
   211         }
       
   212     User::Leave( KErrNotFound) ;
       
   213     return KErrNotFound;
       
   214     }
       
   215 
       
   216 // -----------------------------------------------------------------------------
       
   217 /** 
       
   218  * CTsBackstepping::IsEmbededApp
       
   219  */
       
   220 TBool CTsBackstepping::IsEmbededApp( 
       
   221             const RWsSession::TWindowGroupChainInfo &aWindowGroupInfo ) const 
       
   222     {
       
   223     return 0 < aWindowGroupInfo.iParentId;
       
   224     }
       
   225 
       
   226 // -----------------------------------------------------------------------------
       
   227 /** 
       
   228  * CTsBackstepping::GetUidFromWindowGroupL
       
   229  */
       
   230 TUid CTsBackstepping::GetUidFromWindowGroupL( MTsResourceManager &aResource, 
       
   231                                               TInt aWindowGroupId ) const
       
   232     {
       
   233     TUid retVal(TUid::Null());
       
   234     CApaWindowGroupName *windowGroupName = 
       
   235             CApaWindowGroupName::NewLC( aResource.WsSession() );
       
   236     windowGroupName->ConstructFromWgIdL( aWindowGroupId );
       
   237     retVal = windowGroupName->AppUid();
       
   238     CleanupStack::PopAndDestroy( windowGroupName );
       
   239     return retVal;
       
   240     }
       
   241 
       
   242 // end of file