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 ); |
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 |