taskswitcher/backstepping/src/tsbackstepping.cpp
author hgs
Wed, 06 Oct 2010 16:00:22 +0300
changeset 125 26079c1bb561
parent 119 50e220be30d1
permissions -rw-r--r--
201039_01
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"
125
26079c1bb561 201039_01
hgs
parents: 119
diff changeset
    31
#include "tsrunningapp.h"
26079c1bb561 201039_01
hgs
parents: 119
diff changeset
    32
#include "tsrunningappstorage.h"
26079c1bb561 201039_01
hgs
parents: 119
diff changeset
    33
#include "tsresourcemanager.h"
119
hgs
parents: 116
diff changeset
    34
/**
hgs
parents: 116
diff changeset
    35
 * String to switch hsapplication to IDLE state using activity framework
hgs
parents: 116
diff changeset
    36
 */
116
hgs
parents:
diff changeset
    37
_LIT(KHsActivactionUri, "appto://20022F35?activityname=HsIdleView&activityinbackground=true");
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    40
/** 
119
hgs
parents: 116
diff changeset
    41
 *  Symbian two-phases constructor. Allocate create and initialize backstepping engine
hgs
parents: 116
diff changeset
    42
 *  Instance is pushed int cleanup stack.
hgs
parents: 116
diff changeset
    43
 *  @param aMonitor - window group changes monitor
hgs
parents: 116
diff changeset
    44
 *  @return address to backstepping engine
116
hgs
parents:
diff changeset
    45
 */
hgs
parents:
diff changeset
    46
CTsBackstepping* CTsBackstepping::NewL( MTsWindowGroupsMonitor& aMonitor )
hgs
parents:
diff changeset
    47
    {
hgs
parents:
diff changeset
    48
    CTsBackstepping* self = CTsBackstepping::NewLC( aMonitor );
hgs
parents:
diff changeset
    49
    CleanupStack::Pop( self );
hgs
parents:
diff changeset
    50
    return self;
hgs
parents:
diff changeset
    51
    }
hgs
parents:
diff changeset
    52
hgs
parents:
diff changeset
    53
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    54
/** 
119
hgs
parents: 116
diff changeset
    55
 *  Symbian two-phases constructor. Allocate create and initialize backstepping engine
hgs
parents: 116
diff changeset
    56
 *  @param aMonitor - window group changes monitor
hgs
parents: 116
diff changeset
    57
 *  @return address to backstepping engine
116
hgs
parents:
diff changeset
    58
 */
hgs
parents:
diff changeset
    59
CTsBackstepping* CTsBackstepping::NewLC( MTsWindowGroupsMonitor& aMonitor )
hgs
parents:
diff changeset
    60
    { 
hgs
parents:
diff changeset
    61
    CTsBackstepping* self = new (ELeave) CTsBackstepping( aMonitor );
hgs
parents:
diff changeset
    62
    CleanupStack::PushL( self );
hgs
parents:
diff changeset
    63
    self->ConstructL();
hgs
parents:
diff changeset
    64
    return self;
hgs
parents:
diff changeset
    65
    }
hgs
parents:
diff changeset
    66
hgs
parents:
diff changeset
    67
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    68
/** 
119
hgs
parents: 116
diff changeset
    69
 * Constructor.
hgs
parents: 116
diff changeset
    70
 * @param aMonitor - window group changes monitor
116
hgs
parents:
diff changeset
    71
 */
hgs
parents:
diff changeset
    72
CTsBackstepping::CTsBackstepping( MTsWindowGroupsMonitor &aMonitor )
hgs
parents:
diff changeset
    73
:
125
26079c1bb561 201039_01
hgs
parents: 119
diff changeset
    74
CTsWindowGroupsObserverBase( aMonitor ), iHsWasFirst(ETrue)
116
hgs
parents:
diff changeset
    75
    {
hgs
parents:
diff changeset
    76
    }
hgs
parents:
diff changeset
    77
hgs
parents:
diff changeset
    78
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    79
/** 
hgs
parents:
diff changeset
    80
 *  CTsBackstepping::~CTsBackstepping
hgs
parents:
diff changeset
    81
 *  deconstructor
hgs
parents:
diff changeset
    82
 */
hgs
parents:
diff changeset
    83
CTsBackstepping::~CTsBackstepping()
hgs
parents:
diff changeset
    84
    {
hgs
parents:
diff changeset
    85
    delete iFilter;
hgs
parents:
diff changeset
    86
    }
hgs
parents:
diff changeset
    87
hgs
parents:
diff changeset
    88
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
    89
/** 
119
hgs
parents: 116
diff changeset
    90
 *  Symbian second-phase constructor. 
hgs
parents: 116
diff changeset
    91
 *  Subscribe to window group monitor events (using BaseConstructL) and allocate
hgs
parents: 116
diff changeset
    92
 *  filtering list
116
hgs
parents:
diff changeset
    93
 */
hgs
parents:
diff changeset
    94
void CTsBackstepping::ConstructL ()
hgs
parents:
diff changeset
    95
    {
hgs
parents:
diff changeset
    96
    BaseConstructL();
hgs
parents:
diff changeset
    97
    iFilter = CTsBacksteppingFilter::NewL();
hgs
parents:
diff changeset
    98
    }
hgs
parents:
diff changeset
    99
hgs
parents:
diff changeset
   100
// -----------------------------------------------------------------------------
119
hgs
parents: 116
diff changeset
   101
/**
hgs
parents: 116
diff changeset
   102
 * Analyzes window stack and move homescreen to proper position 
hgs
parents: 116
diff changeset
   103
 * Interface implementation.
hgs
parents: 116
diff changeset
   104
 * @see MTsWindowGroupsObserver::HandleWindowGroupChanged
116
hgs
parents:
diff changeset
   105
 */
hgs
parents:
diff changeset
   106
void CTsBackstepping::HandleWindowGroupChanged( 
119
hgs
parents: 116
diff changeset
   107
                                MTsResourceManager &aResources, 
hgs
parents: 116
diff changeset
   108
                                const MTsRunningApplicationStorage& aStorage )
hgs
parents: 116
diff changeset
   109
116
hgs
parents:
diff changeset
   110
    {
hgs
parents:
diff changeset
   111
    RDebug::Print(_L("[Backstepping] started"));
119
hgs
parents: 116
diff changeset
   112
    TRAP_IGNORE( HandleWindowGroupChangedL( aResources, aStorage ) );
116
hgs
parents:
diff changeset
   113
    RDebug::Print(_L("[Backstepping] finished"));
hgs
parents:
diff changeset
   114
    }
hgs
parents:
diff changeset
   115
hgs
parents:
diff changeset
   116
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   117
/** 
hgs
parents:
diff changeset
   118
 * Analyzes window stack and move homescreen to proper position
119
hgs
parents: 116
diff changeset
   119
 * @see MTsWindowGroupsObserver::HandleWindowGroupChanged from param info
116
hgs
parents:
diff changeset
   120
 */
hgs
parents:
diff changeset
   121
void CTsBackstepping::HandleWindowGroupChangedL( 
119
hgs
parents: 116
diff changeset
   122
                                 MTsResourceManager &aResources, 
hgs
parents: 116
diff changeset
   123
                                 const MTsRunningApplicationStorage& aStorage )
116
hgs
parents:
diff changeset
   124
    {
hgs
parents:
diff changeset
   125
    // calculate the desired position of Homescreen
119
hgs
parents: 116
diff changeset
   126
    const TInt currentHsOffset( HomescreenOffsetL( aStorage ) );
116
hgs
parents:
diff changeset
   127
    TInt optimalOffset(1);
hgs
parents:
diff changeset
   128
    TInt targetHsOffset(currentHsOffset);
119
hgs
parents: 116
diff changeset
   129
    TBool isFirst(ETrue);
116
hgs
parents:
diff changeset
   130
    for( TInt offset(0); offset < currentHsOffset; ++offset ) 
hgs
parents:
diff changeset
   131
        {
119
hgs
parents: 116
diff changeset
   132
        RDebug::Print( _L("[Backstepping] application: %08x"), 
hgs
parents: 116
diff changeset
   133
                       aStorage[offset].UidL().iUid );
hgs
parents: 116
diff changeset
   134
        if( TUid::Null() != aStorage[offset].UidL() )
116
hgs
parents:
diff changeset
   135
            {
119
hgs
parents: 116
diff changeset
   136
            isFirst = EFalse;
hgs
parents: 116
diff changeset
   137
            if( aStorage[offset].IsEmbeded())
116
hgs
parents:
diff changeset
   138
                {
119
hgs
parents: 116
diff changeset
   139
                targetHsOffset = aStorage.ParentIndex(aStorage[offset])+ 1;
116
hgs
parents:
diff changeset
   140
                } 
119
hgs
parents: 116
diff changeset
   141
            else if (!iFilter->isBlocked( aStorage[offset].UidL() ))
116
hgs
parents:
diff changeset
   142
                {
hgs
parents:
diff changeset
   143
                if(offset + 1 < currentHsOffset && 
119
hgs
parents: 116
diff changeset
   144
                   aStorage[offset+1].UidL() == TUid::Null() ) 
116
hgs
parents:
diff changeset
   145
                    {
hgs
parents:
diff changeset
   146
                    ++optimalOffset;
hgs
parents:
diff changeset
   147
                    }
hgs
parents:
diff changeset
   148
                targetHsOffset = optimalOffset;
hgs
parents:
diff changeset
   149
                }
hgs
parents:
diff changeset
   150
            break;
hgs
parents:
diff changeset
   151
            } 
hgs
parents:
diff changeset
   152
        else
hgs
parents:
diff changeset
   153
            {
hgs
parents:
diff changeset
   154
            ++optimalOffset;
hgs
parents:
diff changeset
   155
            }
hgs
parents:
diff changeset
   156
        }
119
hgs
parents: 116
diff changeset
   157
    SwitchToIdleStateL(aResources, isFirst);
116
hgs
parents:
diff changeset
   158
    // change windows order if necessary
hgs
parents:
diff changeset
   159
    if(targetHsOffset != currentHsOffset)
hgs
parents:
diff changeset
   160
        {
hgs
parents:
diff changeset
   161
        RDebug::Print(_L("[Backstepping] about to change window groups order"));
119
hgs
parents: 116
diff changeset
   162
        aResources.WsSession().SetWindowGroupOrdinalPosition( 
hgs
parents: 116
diff changeset
   163
                                    aStorage[currentHsOffset].WindowGroupId(), 
hgs
parents: 116
diff changeset
   164
                                    targetHsOffset );
116
hgs
parents:
diff changeset
   165
        }
hgs
parents:
diff changeset
   166
    }
hgs
parents:
diff changeset
   167
hgs
parents:
diff changeset
   168
// -----------------------------------------------------------------------------
hgs
parents:
diff changeset
   169
/** 
119
hgs
parents: 116
diff changeset
   170
 * Find and return current position of hsapplication on window server stack
hgs
parents: 116
diff changeset
   171
 * @param aStorage - storage with running app info
hgs
parents: 116
diff changeset
   172
 * @return position of hsapplication on window server stack
116
hgs
parents:
diff changeset
   173
 */
hgs
parents:
diff changeset
   174
TInt CTsBackstepping::HomescreenOffsetL( 
119
hgs
parents: 116
diff changeset
   175
                        const MTsRunningApplicationStorage& aStorage ) const 
116
hgs
parents:
diff changeset
   176
    {
hgs
parents:
diff changeset
   177
    TInt offset( KErrNotFound );
119
hgs
parents: 116
diff changeset
   178
    for( TInt iter(0); KErrNotFound == offset && iter < aStorage.Count(); ++iter )
116
hgs
parents:
diff changeset
   179
        {
119
hgs
parents: 116
diff changeset
   180
        if( KHsCategoryUid == aStorage[iter].UidL() )
116
hgs
parents:
diff changeset
   181
            {
hgs
parents:
diff changeset
   182
            offset = iter;
hgs
parents:
diff changeset
   183
            }
hgs
parents:
diff changeset
   184
        }
hgs
parents:
diff changeset
   185
    User::LeaveIfError( offset );
hgs
parents:
diff changeset
   186
    return offset;
hgs
parents:
diff changeset
   187
    }
hgs
parents:
diff changeset
   188
hgs
parents:
diff changeset
   189
// -----------------------------------------------------------------------------
119
hgs
parents: 116
diff changeset
   190
/**
hgs
parents: 116
diff changeset
   191
 * Change hsapplication state to IDLE if moves to background
hgs
parents: 116
diff changeset
   192
 * @param aResources - OS resources manager
hgs
parents: 116
diff changeset
   193
 * @param aIsFrst - flag to inform if hsapplication is in foreground
116
hgs
parents:
diff changeset
   194
 */
119
hgs
parents: 116
diff changeset
   195
void CTsBackstepping::SwitchToIdleStateL(MTsResourceManager& aResources, 
hgs
parents: 116
diff changeset
   196
                                         TBool aIsFirst)
116
hgs
parents:
diff changeset
   197
    {
119
hgs
parents: 116
diff changeset
   198
    // switch Homescreen to Idle state if Homescreen is not in foreground and is in different state
hgs
parents: 116
diff changeset
   199
    if( iHsWasFirst && !aIsFirst )
116
hgs
parents:
diff changeset
   200
        {
119
hgs
parents: 116
diff changeset
   201
        TInt hsState( EHomeScreenIdleState );
hgs
parents: 116
diff changeset
   202
        User::LeaveIfError(RProperty::Get( KHsCategoryUid, 
hgs
parents: 116
diff changeset
   203
                                           KHsCategoryStateKey, 
hgs
parents: 116
diff changeset
   204
                                           hsState ) );
hgs
parents: 116
diff changeset
   205
        if(!(hsState & EHomeScreenWidgetViewActive ) )
116
hgs
parents:
diff changeset
   206
            {
119
hgs
parents: 116
diff changeset
   207
            RDebug::Print(_L("[Backstepping] about to switch HS activity"));
hgs
parents: 116
diff changeset
   208
            CAfActivityLauncher *activityEnabler = 
hgs
parents: 116
diff changeset
   209
                CAfActivityLauncher::NewLC( aResources.ApaSession(), 
hgs
parents: 116
diff changeset
   210
                                            aResources.WsSession() );
hgs
parents: 116
diff changeset
   211
            activityEnabler->launchActivityL( KHsActivactionUri );
hgs
parents: 116
diff changeset
   212
            CleanupStack::PopAndDestroy( activityEnabler );
116
hgs
parents:
diff changeset
   213
            }
hgs
parents:
diff changeset
   214
        }
119
hgs
parents: 116
diff changeset
   215
    iHsWasFirst = aIsFirst;
116
hgs
parents:
diff changeset
   216
    }
hgs
parents:
diff changeset
   217
hgs
parents:
diff changeset
   218
// end of file