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