taskswitcher/backstepping/src/tsbackstepping.cpp
author hgs
Mon, 20 Sep 2010 10:22:22 +0300
changeset 119 50e220be30d1
parent 116 305818acdca4
child 125 26079c1bb561
permissions -rw-r--r--
201037
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
116
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include "tsbackstepping.h"
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
#include <w32std.h>// key event
hgs
parents:
diff changeset
    21
#include <apgwgnam.h>// for CApaWindowGroupName
hgs
parents:
diff changeset
    22
#include <apgtask.h>
hgs
parents:
diff changeset
    23
#include <coedef.h>
hgs
parents:
diff changeset
    24
#include <e32property.h>
hgs
parents:
diff changeset
    25
#include <e32debug.h>
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
#include <homescreendomainpskeys.h>
hgs
parents:
diff changeset
    28
#include <afactivitylauncher.h>
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
#include "tsbacksteppingfilter.h"
hgs
parents:
diff changeset
    31
119
hgs
parents: 116
diff changeset
    32
/**
hgs
parents: 116
diff changeset
    33
 * String to switch hsapplication to IDLE state using activity framework
hgs
parents: 116
diff changeset
    34
 */
116
hgs
parents:
diff changeset
    35
_LIT(KHsActivactionUri, "appto://20022F35?activityname=HsIdleView&activityinbackground=true");
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    38
/** 
119
hgs
parents: 116
diff changeset
    39
 *  Symbian two-phases constructor. Allocate create and initialize backstepping engine
hgs
parents: 116
diff changeset
    40
 *  Instance is pushed int cleanup stack.
hgs
parents: 116
diff changeset
    41
 *  @param aMonitor - window group changes monitor
hgs
parents: 116
diff changeset
    42
 *  @return address to backstepping engine
116
hgs
parents:
diff changeset
    43
 */
hgs
parents:
diff changeset
    44
CTsBackstepping* CTsBackstepping::NewL( MTsWindowGroupsMonitor& aMonitor )
hgs
parents:
diff changeset
    45
    {
hgs
parents:
diff changeset
    46
    CTsBackstepping* self = CTsBackstepping::NewLC( aMonitor );
hgs
parents:
diff changeset
    47
    CleanupStack::Pop( self );
hgs
parents:
diff changeset
    48
    return self;
hgs
parents:
diff changeset
    49
    }
hgs
parents:
diff changeset
    50
hgs
parents:
diff changeset
    51
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    52
/** 
119
hgs
parents: 116
diff changeset
    53
 *  Symbian two-phases constructor. Allocate create and initialize backstepping engine
hgs
parents: 116
diff changeset
    54
 *  @param aMonitor - window group changes monitor
hgs
parents: 116
diff changeset
    55
 *  @return address to backstepping engine
116
hgs
parents:
diff changeset
    56
 */
hgs
parents:
diff changeset
    57
CTsBackstepping* CTsBackstepping::NewLC( MTsWindowGroupsMonitor& aMonitor )
hgs
parents:
diff changeset
    58
    { 
hgs
parents:
diff changeset
    59
    CTsBackstepping* self = new (ELeave) CTsBackstepping( aMonitor );
hgs
parents:
diff changeset
    60
    CleanupStack::PushL( self );
hgs
parents:
diff changeset
    61
    self->ConstructL();
hgs
parents:
diff changeset
    62
    return self;
hgs
parents:
diff changeset
    63
    }
hgs
parents:
diff changeset
    64
hgs
parents:
diff changeset
    65
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    66
/** 
119
hgs
parents: 116
diff changeset
    67
 * Constructor.
hgs
parents: 116
diff changeset
    68
 * @param aMonitor - window group changes monitor
116
hgs
parents:
diff changeset
    69
 */
hgs
parents:
diff changeset
    70
CTsBackstepping::CTsBackstepping( MTsWindowGroupsMonitor &aMonitor )
hgs
parents:
diff changeset
    71
:
119
hgs
parents: 116
diff changeset
    72
CTsWindowGroupsObserver( aMonitor ), iHsWasFirst(ETrue)
116
hgs
parents:
diff changeset
    73
    {
hgs
parents:
diff changeset
    74
    }
hgs
parents:
diff changeset
    75
hgs
parents:
diff changeset
    76
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    77
/** 
hgs
parents:
diff changeset
    78
 *  CTsBackstepping::~CTsBackstepping
hgs
parents:
diff changeset
    79
 *  deconstructor
hgs
parents:
diff changeset
    80
 */
hgs
parents:
diff changeset
    81
CTsBackstepping::~CTsBackstepping()
hgs
parents:
diff changeset
    82
    {
hgs
parents:
diff changeset
    83
    delete iFilter;
hgs
parents:
diff changeset
    84
    }
hgs
parents:
diff changeset
    85
hgs
parents:
diff changeset
    86
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    87
/** 
119
hgs
parents: 116
diff changeset
    88
 *  Symbian second-phase constructor. 
hgs
parents: 116
diff changeset
    89
 *  Subscribe to window group monitor events (using BaseConstructL) and allocate
hgs
parents: 116
diff changeset
    90
 *  filtering list
116
hgs
parents:
diff changeset
    91
 */
hgs
parents:
diff changeset
    92
void CTsBackstepping::ConstructL ()
hgs
parents:
diff changeset
    93
    {
hgs
parents:
diff changeset
    94
    BaseConstructL();
hgs
parents:
diff changeset
    95
    iFilter = CTsBacksteppingFilter::NewL();
hgs
parents:
diff changeset
    96
    }
hgs
parents:
diff changeset
    97
hgs
parents:
diff changeset
    98
// -----------------------------------------------------------------------------
119
hgs
parents: 116
diff changeset
    99
/**
hgs
parents: 116
diff changeset
   100
 * Analyzes window stack and move homescreen to proper position 
hgs
parents: 116
diff changeset
   101
 * Interface implementation.
hgs
parents: 116
diff changeset
   102
 * @see MTsWindowGroupsObserver::HandleWindowGroupChanged
116
hgs
parents:
diff changeset
   103
 */
hgs
parents:
diff changeset
   104
void CTsBackstepping::HandleWindowGroupChanged( 
119
hgs
parents: 116
diff changeset
   105
                                MTsResourceManager &aResources, 
hgs
parents: 116
diff changeset
   106
                                const MTsRunningApplicationStorage& aStorage )
hgs
parents: 116
diff changeset
   107
116
hgs
parents:
diff changeset
   108
    {
hgs
parents:
diff changeset
   109
    RDebug::Print(_L("[Backstepping] started"));
119
hgs
parents: 116
diff changeset
   110
    TRAP_IGNORE( HandleWindowGroupChangedL( aResources, aStorage ) );
116
hgs
parents:
diff changeset
   111
    RDebug::Print(_L("[Backstepping] finished"));
hgs
parents:
diff changeset
   112
    }
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   115
/** 
hgs
parents:
diff changeset
   116
 * Analyzes window stack and move homescreen to proper position
119
hgs
parents: 116
diff changeset
   117
 * @see MTsWindowGroupsObserver::HandleWindowGroupChanged from param info
116
hgs
parents:
diff changeset
   118
 */
hgs
parents:
diff changeset
   119
void CTsBackstepping::HandleWindowGroupChangedL( 
119
hgs
parents: 116
diff changeset
   120
                                 MTsResourceManager &aResources, 
hgs
parents: 116
diff changeset
   121
                                 const MTsRunningApplicationStorage& aStorage )
116
hgs
parents:
diff changeset
   122
    {
hgs
parents:
diff changeset
   123
    // calculate the desired position of Homescreen
119
hgs
parents: 116
diff changeset
   124
    const TInt currentHsOffset( HomescreenOffsetL( aStorage ) );
116
hgs
parents:
diff changeset
   125
    TInt optimalOffset(1);
hgs
parents:
diff changeset
   126
    TInt targetHsOffset(currentHsOffset);
119
hgs
parents: 116
diff changeset
   127
    TBool isFirst(ETrue);
116
hgs
parents:
diff changeset
   128
    for( TInt offset(0); offset < currentHsOffset; ++offset ) 
hgs
parents:
diff changeset
   129
        {
119
hgs
parents: 116
diff changeset
   130
        RDebug::Print( _L("[Backstepping] application: %08x"), 
hgs
parents: 116
diff changeset
   131
                       aStorage[offset].UidL().iUid );
hgs
parents: 116
diff changeset
   132
        if( TUid::Null() != aStorage[offset].UidL() )
116
hgs
parents:
diff changeset
   133
            {
119
hgs
parents: 116
diff changeset
   134
            isFirst = EFalse;
hgs
parents: 116
diff changeset
   135
            if( aStorage[offset].IsEmbeded())
116
hgs
parents:
diff changeset
   136
                {
119
hgs
parents: 116
diff changeset
   137
                targetHsOffset = aStorage.ParentIndex(aStorage[offset])+ 1;
116
hgs
parents:
diff changeset
   138
                } 
119
hgs
parents: 116
diff changeset
   139
            else if (!iFilter->isBlocked( aStorage[offset].UidL() ))
116
hgs
parents:
diff changeset
   140
                {
hgs
parents:
diff changeset
   141
                if(offset + 1 < currentHsOffset && 
119
hgs
parents: 116
diff changeset
   142
                   aStorage[offset+1].UidL() == TUid::Null() ) 
116
hgs
parents:
diff changeset
   143
                    {
hgs
parents:
diff changeset
   144
                    ++optimalOffset;
hgs
parents:
diff changeset
   145
                    }
hgs
parents:
diff changeset
   146
                targetHsOffset = optimalOffset;
hgs
parents:
diff changeset
   147
                }
hgs
parents:
diff changeset
   148
            break;
hgs
parents:
diff changeset
   149
            } 
hgs
parents:
diff changeset
   150
        else
hgs
parents:
diff changeset
   151
            {
hgs
parents:
diff changeset
   152
            ++optimalOffset;
hgs
parents:
diff changeset
   153
            }
hgs
parents:
diff changeset
   154
        }
119
hgs
parents: 116
diff changeset
   155
    SwitchToIdleStateL(aResources, isFirst);
116
hgs
parents:
diff changeset
   156
    // change windows order if necessary
hgs
parents:
diff changeset
   157
    if(targetHsOffset != currentHsOffset)
hgs
parents:
diff changeset
   158
        {
hgs
parents:
diff changeset
   159
        RDebug::Print(_L("[Backstepping] about to change window groups order"));
119
hgs
parents: 116
diff changeset
   160
        aResources.WsSession().SetWindowGroupOrdinalPosition( 
hgs
parents: 116
diff changeset
   161
                                    aStorage[currentHsOffset].WindowGroupId(), 
hgs
parents: 116
diff changeset
   162
                                    targetHsOffset );
116
hgs
parents:
diff changeset
   163
        }
hgs
parents:
diff changeset
   164
    }
hgs
parents:
diff changeset
   165
hgs
parents:
diff changeset
   166
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   167
/** 
119
hgs
parents: 116
diff changeset
   168
 * Find and return current position of hsapplication on window server stack
hgs
parents: 116
diff changeset
   169
 * @param aStorage - storage with running app info
hgs
parents: 116
diff changeset
   170
 * @return position of hsapplication on window server stack
116
hgs
parents:
diff changeset
   171
 */
hgs
parents:
diff changeset
   172
TInt CTsBackstepping::HomescreenOffsetL( 
119
hgs
parents: 116
diff changeset
   173
                        const MTsRunningApplicationStorage& aStorage ) const 
116
hgs
parents:
diff changeset
   174
    {
hgs
parents:
diff changeset
   175
    TInt offset( KErrNotFound );
119
hgs
parents: 116
diff changeset
   176
    for( TInt iter(0); KErrNotFound == offset && iter < aStorage.Count(); ++iter )
116
hgs
parents:
diff changeset
   177
        {
119
hgs
parents: 116
diff changeset
   178
        if( KHsCategoryUid == aStorage[iter].UidL() )
116
hgs
parents:
diff changeset
   179
            {
hgs
parents:
diff changeset
   180
            offset = iter;
hgs
parents:
diff changeset
   181
            }
hgs
parents:
diff changeset
   182
        }
hgs
parents:
diff changeset
   183
    User::LeaveIfError( offset );
hgs
parents:
diff changeset
   184
    return offset;
hgs
parents:
diff changeset
   185
    }
hgs
parents:
diff changeset
   186
hgs
parents:
diff changeset
   187
// -----------------------------------------------------------------------------
119
hgs
parents: 116
diff changeset
   188
/**
hgs
parents: 116
diff changeset
   189
 * Change hsapplication state to IDLE if moves to background
hgs
parents: 116
diff changeset
   190
 * @param aResources - OS resources manager
hgs
parents: 116
diff changeset
   191
 * @param aIsFrst - flag to inform if hsapplication is in foreground
116
hgs
parents:
diff changeset
   192
 */
119
hgs
parents: 116
diff changeset
   193
void CTsBackstepping::SwitchToIdleStateL(MTsResourceManager& aResources, 
hgs
parents: 116
diff changeset
   194
                                         TBool aIsFirst)
116
hgs
parents:
diff changeset
   195
    {
119
hgs
parents: 116
diff changeset
   196
    // switch Homescreen to Idle state if Homescreen is not in foreground and is in different state
hgs
parents: 116
diff changeset
   197
    if( iHsWasFirst && !aIsFirst )
116
hgs
parents:
diff changeset
   198
        {
119
hgs
parents: 116
diff changeset
   199
        TInt hsState( EHomeScreenIdleState );
hgs
parents: 116
diff changeset
   200
        User::LeaveIfError(RProperty::Get( KHsCategoryUid, 
hgs
parents: 116
diff changeset
   201
                                           KHsCategoryStateKey, 
hgs
parents: 116
diff changeset
   202
                                           hsState ) );
hgs
parents: 116
diff changeset
   203
        if(!(hsState & EHomeScreenWidgetViewActive ) )
116
hgs
parents:
diff changeset
   204
            {
119
hgs
parents: 116
diff changeset
   205
            RDebug::Print(_L("[Backstepping] about to switch HS activity"));
hgs
parents: 116
diff changeset
   206
            CAfActivityLauncher *activityEnabler = 
hgs
parents: 116
diff changeset
   207
                CAfActivityLauncher::NewLC( aResources.ApaSession(), 
hgs
parents: 116
diff changeset
   208
                                            aResources.WsSession() );
hgs
parents: 116
diff changeset
   209
            activityEnabler->launchActivityL( KHsActivactionUri );
hgs
parents: 116
diff changeset
   210
            CleanupStack::PopAndDestroy( activityEnabler );
116
hgs
parents:
diff changeset
   211
            }
hgs
parents:
diff changeset
   212
        }
119
hgs
parents: 116
diff changeset
   213
    iHsWasFirst = aIsFirst;
116
hgs
parents:
diff changeset
   214
    }
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
// end of file