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