|
1 /* |
|
2 * Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Server side implementation of AVKON System |
|
15 * Graphics Coordinator. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "AknEikSgcs.h" |
|
21 #include <eikenv.h> |
|
22 #include "eiksrvsp.h" |
|
23 #include <AknSgcc.h> |
|
24 #include <aknenv.h> |
|
25 #include <AknDef.h> |
|
26 #include <aknappui.h> |
|
27 #include <e32property.h> |
|
28 #include <UikonInternalPSKeys.h> |
|
29 #include <avkondomainpskeys.h> |
|
30 #include <AknSettingCache.h> |
|
31 #include "AknCapServerEntry.h" |
|
32 #include <aknconsts.h> |
|
33 #include "winchangemonitor.h" |
|
34 #include "akncapserverdebug.h" |
|
35 #include "akncompaif.h" |
|
36 |
|
37 #include <AknsConstants.h> |
|
38 #include <AknsUtils.h> |
|
39 #include <AknIconUtils.h> |
|
40 #include <AknUtils.h> |
|
41 #include <aknlayoutscalable_avkon.cdl.h> |
|
42 #include "avkoninternalpskeys.h" |
|
43 #include <layoutmetadata.cdl.h> |
|
44 #include <AknTaskList.h> |
|
45 #ifdef RD_UI_TRANSITION_EFFECTS_LAYOUT_SWITCH |
|
46 #include <akntranseffect.h> |
|
47 #include <akntransitionutils.h> |
|
48 #endif |
|
49 |
|
50 #include <LayoutPack.cdl.h> |
|
51 #include <CdlRefs.h> |
|
52 const TInt KCdlEComInterfaceId = 0x101f8243; |
|
53 |
|
54 const TInt KLayoutChangeTimeout = 2000000; // 2s |
|
55 const TInt KWgStatesGranularity = 4; |
|
56 const TInt KRelinquishedThreadListGranularity = 4; |
|
57 const TInt KRemoveBlankDelay = 200000; // 0.2s |
|
58 // Drawing is slower when transparency is enabled. The time needs to be |
|
59 // big enough to account for slowest drawing application. |
|
60 const TInt KRemoveBlankDelayTransparency = 1500000; // 1.5s |
|
61 |
|
62 // 4s should be enough for foreground app's operations to complete. |
|
63 const TInt KRestoreThreadPriorityDelay = 4000000; |
|
64 |
|
65 // Screensaver application UID |
|
66 const TUid KScreensaverAppUid = { 0x100056CF }; |
|
67 |
|
68 // Read pass policy |
|
69 _LIT_SECURITY_POLICY_PASS(KPassReadPolicy); |
|
70 |
|
71 // Policy requiring write device data capability. |
|
72 _LIT_SECURITY_POLICY_C1(KWriteDDPolicy, ECapabilityWriteDeviceData); |
|
73 |
|
74 enum TWgStateFlags |
|
75 { |
|
76 EWgStateFullScreen, |
|
77 EWgStatePartialForeground, |
|
78 EWgStateUnderstandsPartialForeground, |
|
79 EWgStateLegacyLayout, |
|
80 EWgStateOrientationSpecified, |
|
81 EWgStateOrientationLandscape |
|
82 }; |
|
83 |
|
84 enum TSetLayoutBlankStep |
|
85 { |
|
86 ESetLayoutBlankBeforeLayoutLoad, |
|
87 ESetLayoutBlankBetweenLayoutLoadAndScreenRotate, |
|
88 ESetLayoutBlankAfterScreenRotate, |
|
89 ESetLayoutBlankNever |
|
90 }; |
|
91 |
|
92 NONSHARABLE_CLASS(CAknSgcServerImpl) : public CAknSgcImpl |
|
93 { |
|
94 public: |
|
95 CAknSgcServerImpl(CEikSgcServer* aServer); |
|
96 void MoveApp(TInt aAppWindowGroupId, TSgcMoveAppToWhere aWhere); |
|
97 |
|
98 private: |
|
99 CEikSgcServer* iServer; |
|
100 }; |
|
101 |
|
102 |
|
103 class CLayoutChangeCallBack : public CActive |
|
104 { |
|
105 public: |
|
106 CLayoutChangeCallBack(CEikSgcServer* aSgc); |
|
107 void ConstructL(); |
|
108 ~CLayoutChangeCallBack(); |
|
109 |
|
110 void RestartTimerL(); |
|
111 |
|
112 private: |
|
113 void DoCancel(); |
|
114 void RunL(); |
|
115 |
|
116 static TInt ThreadFunc(TAny* aStat); |
|
117 |
|
118 static TInt TimeoutCallback(TAny* aThis); |
|
119 void DoTimeout(); |
|
120 |
|
121 private: |
|
122 CEikSgcServer* iSgc; |
|
123 RThread iThread; |
|
124 TThreadId iMain; |
|
125 CPeriodic* iTimeout; |
|
126 }; |
|
127 |
|
128 CLayoutChangeCallBack::CLayoutChangeCallBack(CEikSgcServer* aSgc) |
|
129 : CActive(CActive::EPriorityLow), iSgc(aSgc), iMain(RThread().Id()) |
|
130 { |
|
131 CActiveScheduler::Add(this); |
|
132 } |
|
133 |
|
134 void CLayoutChangeCallBack::ConstructL() |
|
135 { |
|
136 // Create the thread. |
|
137 User::LeaveIfError(iThread.Create(KNullDesC, ThreadFunc, 0x400, NULL, this)); |
|
138 iThread.SetPriority(EPriorityAbsoluteBackground); |
|
139 |
|
140 // Set the active status & start the thread. |
|
141 iStatus = KRequestPending; |
|
142 SetActive(); |
|
143 iThread.Resume(); |
|
144 |
|
145 RestartTimerL(); |
|
146 } |
|
147 |
|
148 void CLayoutChangeCallBack::RestartTimerL() |
|
149 { |
|
150 delete iTimeout; |
|
151 iTimeout = NULL; |
|
152 iTimeout = CPeriodic::NewL(CActive::EPriorityStandard); |
|
153 iTimeout->Start(KLayoutChangeTimeout, KLayoutChangeTimeout, TCallBack(TimeoutCallback, this)); |
|
154 } |
|
155 |
|
156 CLayoutChangeCallBack::~CLayoutChangeCallBack() |
|
157 { |
|
158 Cancel(); |
|
159 iThread.Close(); |
|
160 delete iTimeout; |
|
161 } |
|
162 |
|
163 void CLayoutChangeCallBack::DoCancel() |
|
164 { |
|
165 iThread.Terminate(0); |
|
166 |
|
167 // Only complete the request if not yet completed by the background thread. |
|
168 if ( iStatus == KRequestPending ) |
|
169 { |
|
170 TRequestStatus* pStatus = &iStatus; |
|
171 User::RequestComplete(pStatus, KErrCancel); |
|
172 } |
|
173 } |
|
174 |
|
175 void CLayoutChangeCallBack::RunL() |
|
176 { |
|
177 iSgc->HandleLayoutChangeCallBackL(); |
|
178 } |
|
179 |
|
180 |
|
181 // --------------------------------------------------------------------------- |
|
182 // CLayoutChangeCallBack::ThreadFunc |
|
183 // Thread entry point function. |
|
184 // --------------------------------------------------------------------------- |
|
185 // |
|
186 TInt CLayoutChangeCallBack::ThreadFunc( TAny* aLayoutChangeCallBack ) |
|
187 { |
|
188 CLayoutChangeCallBack* self = |
|
189 static_cast<CLayoutChangeCallBack*>(aLayoutChangeCallBack); |
|
190 RThread main; |
|
191 if (KErrNone == main.Open(self->iMain)) |
|
192 { |
|
193 TRequestStatus* pStatus = &self->iStatus; |
|
194 main.RequestComplete(pStatus, KErrNone); |
|
195 main.Close(); |
|
196 } |
|
197 return KErrNone; |
|
198 } |
|
199 |
|
200 TInt CLayoutChangeCallBack::TimeoutCallback( TAny* aThis ) |
|
201 { |
|
202 static_cast<CLayoutChangeCallBack*>( aThis )->DoTimeout(); |
|
203 return EFalse; |
|
204 } |
|
205 |
|
206 void CLayoutChangeCallBack::DoTimeout() |
|
207 { |
|
208 TRAP_IGNORE( iSgc->HandleLayoutChangeCallBackL() ); |
|
209 } |
|
210 |
|
211 |
|
212 CEikSgcServer::TWgState::TWgState() |
|
213 : iWgId(0), iSpLayout(0), iSpFlags(0), iAppScreenMode(KAknScreenModeUnset) |
|
214 { |
|
215 // Default state for window groups is full screen - handles non |
|
216 // avkon apps. |
|
217 iFlags.Set(EWgStateFullScreen); |
|
218 } |
|
219 |
|
220 CEikSgcServer::TWgState::TWgState(TInt aWgId) |
|
221 : iWgId(aWgId), iSpLayout(0), iSpFlags(0), iAppScreenMode(KAknScreenModeUnset) |
|
222 { |
|
223 // Default state for window groups is full screen - handles non |
|
224 // avkon apps. |
|
225 iFlags.Set(EWgStateFullScreen); |
|
226 } |
|
227 |
|
228 inline TInt CEikSgcServer::TWgState::WgId() const |
|
229 { |
|
230 return iWgId; |
|
231 } |
|
232 |
|
233 inline void CEikSgcServer::TWgState::SetWgId(TInt aWgId) |
|
234 { |
|
235 iWgId = aWgId; |
|
236 } |
|
237 |
|
238 inline TInt CEikSgcServer::TWgState::SpLayout() const |
|
239 { |
|
240 return iSpLayout; |
|
241 } |
|
242 |
|
243 inline void CEikSgcServer::TWgState::SetSpLayout(TInt aSpLayout) |
|
244 { |
|
245 iSpLayout = aSpLayout; |
|
246 } |
|
247 |
|
248 inline TInt CEikSgcServer::TWgState::SpFlags() const |
|
249 { |
|
250 return iSpFlags; |
|
251 } |
|
252 |
|
253 inline void CEikSgcServer::TWgState::SetSpFlags(TInt aSpFlags) |
|
254 { |
|
255 iSpFlags = aSpFlags; |
|
256 } |
|
257 |
|
258 inline TBool CEikSgcServer::TWgState::IsFullScreen() const |
|
259 { |
|
260 return iFlags[EWgStateFullScreen]; |
|
261 } |
|
262 |
|
263 inline void CEikSgcServer::TWgState::SetFullScreen(TBool aFullScreen) |
|
264 { |
|
265 iFlags.Assign(EWgStateFullScreen, aFullScreen); |
|
266 } |
|
267 |
|
268 inline TBool CEikSgcServer::TWgState::IsPartialForeground() const |
|
269 { |
|
270 return iFlags[EWgStatePartialForeground]; |
|
271 } |
|
272 |
|
273 inline void CEikSgcServer::TWgState::SetPartialForeground(TBool aPartialForeground) |
|
274 { |
|
275 iFlags.Assign(EWgStatePartialForeground, aPartialForeground); |
|
276 } |
|
277 |
|
278 inline TBool CEikSgcServer::TWgState::UnderstandsPartialForeground() const |
|
279 { |
|
280 return iFlags[EWgStateUnderstandsPartialForeground]; |
|
281 } |
|
282 |
|
283 inline void CEikSgcServer::TWgState::SetUnderstandsPartialForeground(TBool aPartialForeground) |
|
284 { |
|
285 iFlags.Assign(EWgStateUnderstandsPartialForeground, aPartialForeground); |
|
286 } |
|
287 |
|
288 inline TBool CEikSgcServer::TWgState::IsLegacyLayout() const |
|
289 { |
|
290 return iFlags[EWgStateLegacyLayout]; |
|
291 } |
|
292 |
|
293 inline void CEikSgcServer::TWgState::SetLegacyLayout(TBool aLegacyLayout) |
|
294 { |
|
295 iFlags.Assign(EWgStateLegacyLayout, aLegacyLayout); |
|
296 } |
|
297 |
|
298 inline TBool CEikSgcServer::TWgState::IsOrientationSpecified() const |
|
299 { |
|
300 return iFlags[EWgStateOrientationSpecified]; |
|
301 } |
|
302 |
|
303 inline void CEikSgcServer::TWgState::SetOrientationSpecified(TBool aOrientationSpecified) |
|
304 { |
|
305 iFlags.Assign(EWgStateOrientationSpecified, aOrientationSpecified); |
|
306 } |
|
307 |
|
308 inline TBool CEikSgcServer::TWgState::IsOrientationLandscape() const |
|
309 { |
|
310 return iFlags[EWgStateOrientationLandscape]; |
|
311 } |
|
312 |
|
313 inline void CEikSgcServer::TWgState::SetOrientationLandscape(TBool aOrientationLandscape) |
|
314 { |
|
315 iFlags.Assign(EWgStateOrientationLandscape, aOrientationLandscape); |
|
316 } |
|
317 |
|
318 inline TInt CEikSgcServer::TWgState::AppScreenMode() const |
|
319 { |
|
320 return iAppScreenMode; |
|
321 } |
|
322 |
|
323 inline void CEikSgcServer::TWgState::SetAppScreenMode(TInt aAppScreenMode) |
|
324 { |
|
325 iAppScreenMode = aAppScreenMode; |
|
326 } |
|
327 |
|
328 CEikSgcServer* CEikSgcServer::NewL() |
|
329 { |
|
330 CEikSgcServer* self = new(ELeave) CEikSgcServer(); |
|
331 CleanupStack::PushL(self); |
|
332 self->ConstructL(); |
|
333 CleanupStack::Pop(self); |
|
334 return self; |
|
335 } |
|
336 |
|
337 CEikSgcServer::CEikSgcServer() |
|
338 : iWs(CEikonEnv::Static()->WsSession()), |
|
339 iLastScreenModeSet(-1), |
|
340 iRelinquishedThreads(KRelinquishedThreadListGranularity), |
|
341 iSetLayoutBlankStep(ESetLayoutBlankBeforeLayoutLoad) |
|
342 { |
|
343 } |
|
344 |
|
345 void CEikSgcServer::ConstructL() |
|
346 { |
|
347 iWgStates = new(ELeave) CWgStates(KWgStatesGranularity); |
|
348 |
|
349 TInt err = RProperty::Define(KPSUidUikon, KUikPreferredOrientation, RProperty::EInt); |
|
350 User::LeaveIfError(err); |
|
351 |
|
352 err = RProperty::Define( |
|
353 KPSUidAvkonDomain, |
|
354 KAknNotificationsInIdleAllowed, |
|
355 RProperty::EInt, |
|
356 KPassReadPolicy, |
|
357 KWriteDDPolicy); |
|
358 User::LeaveIfError(err); |
|
359 #if FADE_BITMAP |
|
360 |
|
361 err = RProperty::Define(KPSUidAvkonInternal, KAknFadeBitmapHandle, |
|
362 RProperty::EInt, |
|
363 KPassReadPolicy, |
|
364 KWriteDDPolicy); |
|
365 User::LeaveIfError(err); |
|
366 err = RProperty::Define(KPSUidAvkonInternal, KAknFadeMaskHandle, |
|
367 RProperty::EInt, |
|
368 KPassReadPolicy, |
|
369 KWriteDDPolicy); |
|
370 User::LeaveIfError(err); |
|
371 #endif |
|
372 |
|
373 err = RProperty::Define(KPSUidAvkonInternal, KAknFadeColorHandle, |
|
374 RProperty::EInt, |
|
375 KPassReadPolicy, |
|
376 KWriteDDPolicy); |
|
377 User::LeaveIfError(err); |
|
378 |
|
379 err = RProperty::Define(KPSUidAvkonInternal, KAknFadeBlackMapHandle, |
|
380 RProperty::EInt, |
|
381 KPassReadPolicy, |
|
382 KWriteDDPolicy); |
|
383 User::LeaveIfError(err); |
|
384 err = RProperty::Define(KPSUidAvkonInternal, KAknFadeWhiteMapHandle, |
|
385 RProperty::EInt, |
|
386 KPassReadPolicy, |
|
387 KWriteDDPolicy); |
|
388 User::LeaveIfError(err); |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 #ifndef TFX_USE_WCHANGE_EVENT |
|
394 iWinChange = CWindowChangeMonitor::NewL(iWs); |
|
395 #endif |
|
396 |
|
397 CAknSgcServerImpl* sgcImpl = new(ELeave) CAknSgcServerImpl(this); |
|
398 // CAknSgcClient takes ownership of sgcImpl and replaces |
|
399 // existing client impl with it. |
|
400 CAknSgcClient::SetImpl(sgcImpl); |
|
401 |
|
402 // Touch compatibility mode |
|
403 iAvkonAppUiBase->MopGetObjectNoChaining(iTouchCompaModeIf); |
|
404 iTouchCompaScreenMode = KErrNotFound; |
|
405 if (iTouchCompaModeIf) |
|
406 { |
|
407 iTouchCompaScreenMode = iTouchCompaModeIf->FindCompaScreenMode(); |
|
408 } |
|
409 |
|
410 // ECom notifier for ILD installations |
|
411 TCallBack callback(CEikSgcServer::LayoutInstallationCallBack, this); |
|
412 iLayoutNotifier = CEComPluginNotifier::NewL(KNullUid, callback); |
|
413 iLayoutNotifier->Start(); |
|
414 EComPluginUtils::GetInfoArrayL(TUid::Uid(KCdlEComInterfaceId), iPrevPluginInfo); |
|
415 } |
|
416 |
|
417 TInt CEikSgcServer::LayoutInstallationCallBack(TAny* aPtr) |
|
418 { |
|
419 return ((CEikSgcServer*)aPtr)->RefreshLayoutIfRequiredL(); |
|
420 } |
|
421 |
|
422 TInt CEikSgcServer::RefreshLayoutIfRequiredL() |
|
423 { |
|
424 REComPluginInfoArray newPlugins; |
|
425 EComPluginUtils::GetInfoArrayL(TUid::Uid(KCdlEComInterfaceId), newPlugins); |
|
426 REComPluginInfoArray newPluginsCopy = newPlugins; |
|
427 |
|
428 // Remove any plugins that haven't changed from the arrays |
|
429 TInt prevCount = iPrevPluginInfo.Count(); |
|
430 while(prevCount > 0) |
|
431 { |
|
432 prevCount--; |
|
433 TUid prevUid = (iPrevPluginInfo[prevCount]).iUid; |
|
434 TInt prevVer = (iPrevPluginInfo[prevCount]).iVersion; |
|
435 TInt newCount = newPlugins.Count(); |
|
436 while(newCount > 0) |
|
437 { |
|
438 newCount--; |
|
439 TUid newUid = (newPlugins[newCount]).iUid; |
|
440 TInt newVer = (newPlugins[newCount]).iVersion; |
|
441 if(prevUid == newUid && prevVer == newVer) |
|
442 { |
|
443 newPlugins.Remove(newCount); |
|
444 iPrevPluginInfo.Remove(prevCount); |
|
445 break; |
|
446 } |
|
447 } |
|
448 } |
|
449 |
|
450 TBool refreshRequired = EFalse; |
|
451 if(iPrevPluginInfo.Count() > 0) |
|
452 { |
|
453 // A plugin has been removed, but we can't check what it contained. |
|
454 refreshRequired = ETrue; |
|
455 } |
|
456 else |
|
457 { |
|
458 // Check through the changed plugins to see whether any contain layout packs |
|
459 _LIT(KLitDllPath, "%S%08x.dll"); |
|
460 const TInt KPathLength = 14; // Drive letter + ":" + UID + ".dll" |
|
461 for(TInt i=0; i<newPlugins.Count(); i++) |
|
462 { |
|
463 TEComPluginInfo imp = newPlugins[i]; |
|
464 TBuf<KPathLength> buf; |
|
465 TDriveName drive(imp.iDrive.Name()); |
|
466 buf.Format(KLitDllPath, &drive, imp.iUid.iUid); |
|
467 |
|
468 CCdlRefCollection* refsInFile = CdlEngine::FileContentsLC(buf); |
|
469 CCdlRefs* refs = CCdlRefs::NewLC(); |
|
470 refs->AppendL(*refsInFile); |
|
471 CCdlRefs* layoutsInFile = refs->SubsetByUidLC(LayoutPack::KCdlInterfaceUid); |
|
472 TInt numLayouts = layoutsInFile->CountRefs(); |
|
473 CleanupStack::PopAndDestroy(3, refsInFile); |
|
474 |
|
475 if(numLayouts > 0) |
|
476 { |
|
477 // Plugin added with layouts, refresh required |
|
478 refreshRequired = ETrue; |
|
479 break; |
|
480 } |
|
481 } |
|
482 } |
|
483 |
|
484 // Send the event if it's needed |
|
485 TInt result = KErrNone; |
|
486 if(refreshRequired) |
|
487 { |
|
488 RWsSession session; |
|
489 TInt err = session.Connect(); |
|
490 if ( err == KErrNone ) |
|
491 { |
|
492 TWsEvent event; |
|
493 event.SetType(KAknILDInstallationLayoutSwitch); |
|
494 result = session.SendEventToAllWindowGroups(event); |
|
495 session.Close(); |
|
496 } |
|
497 } |
|
498 |
|
499 // Store the copy of the new list of plugins for next time |
|
500 iPrevPluginInfo.Reset(); |
|
501 iPrevPluginInfo = newPluginsCopy; |
|
502 |
|
503 return result; |
|
504 } |
|
505 |
|
506 CEikSgcServer::~CEikSgcServer() |
|
507 { |
|
508 delete iFadeBitmap; |
|
509 delete iFadeMask; |
|
510 |
|
511 delete iWinChange; |
|
512 delete iLayoutChangeCallBack; |
|
513 delete iWgStates; |
|
514 delete iRemoveBlankCallBack; |
|
515 delete iLayoutNotifier; |
|
516 } |
|
517 |
|
518 void CEikSgcServer::HandleWindowGroupListChangeL() |
|
519 { |
|
520 CWgIds* wgIds = CreateWgIdListLC(); |
|
521 if (!TestWgListOrderOk(wgIds)) |
|
522 { |
|
523 ReOrderWgStatesL(wgIds); |
|
524 PostChangeRecalcL(); |
|
525 UpdateNotificationsInIdleAllowedKey(); |
|
526 } |
|
527 CleanupStack::PopAndDestroy( wgIds ); |
|
528 } |
|
529 |
|
530 void CEikSgcServer::HandleWindowGroupParamChangeL(TInt aWgId, TBitFlags aAppFlags, TInt aSpLayout, |
|
531 TInt aSpFlags, TInt aAppScreenMode) |
|
532 { |
|
533 LOGTEXT0("CEikSgcServer::HandleWindowGroupParamChangeL - ENTER"); |
|
534 |
|
535 TBool understandsPartialForegroundChanged = EFalse; |
|
536 TBool fullScreenChanged = EFalse; |
|
537 |
|
538 TWgState& state = GetWgStateL(aWgId); |
|
539 |
|
540 const TBool wasFullScreen = state.IsFullScreen(); |
|
541 state.SetFullScreen(aAppFlags[CAknSgcClient::EFullScreen]); |
|
542 const TBool isFullScreen = state.IsFullScreen(); |
|
543 |
|
544 state.SetLegacyLayout(aAppFlags[CAknSgcClient::ELegacyLayout]); |
|
545 state.SetSpLayout(aSpLayout); |
|
546 state.SetSpFlags(aSpFlags); |
|
547 |
|
548 // Check whether understands partial foreground is changed. |
|
549 if (!state.UnderstandsPartialForeground()) |
|
550 { |
|
551 understandsPartialForegroundChanged = ETrue; |
|
552 } |
|
553 state.SetUnderstandsPartialForeground(ETrue); |
|
554 |
|
555 state.SetOrientationSpecified(aAppFlags[CAknSgcClient::EOrientationSpecified]); |
|
556 state.SetOrientationLandscape(aAppFlags[CAknSgcClient::EOrientationLandscape]); |
|
557 state.SetAppScreenMode(aAppScreenMode); |
|
558 PostChangeRecalcL(); |
|
559 |
|
560 // Check whether full screen mode has been changed. |
|
561 fullScreenChanged = (wasFullScreen && !isFullScreen) || (!wasFullScreen && isFullScreen); |
|
562 |
|
563 if (understandsPartialForegroundChanged || fullScreenChanged) |
|
564 { |
|
565 LOGTEXT1(" understandsPartialForegroundChanged: %d", understandsPartialForegroundChanged); |
|
566 LOGTEXT1(" fullScreenChanged: %d", fullScreenChanged); |
|
567 |
|
568 UpdateNotificationsInIdleAllowedKey(); |
|
569 } |
|
570 |
|
571 LOGTEXT0("CEikSgcServer::HandleWindowGroupParamChangeL - EXIT"); |
|
572 } |
|
573 |
|
574 CEikSgcServer::TWgState& CEikSgcServer::GetWgStateL(TInt aWgId) |
|
575 { |
|
576 TInt index = WgStateIndex(aWgId); |
|
577 if (index == KErrNotFound) |
|
578 { |
|
579 iWgStates->AppendL(TWgState(aWgId)); |
|
580 index = iWgStates->Count()-1; |
|
581 } |
|
582 return iWgStates->At(index); |
|
583 } |
|
584 |
|
585 TInt CEikSgcServer::WgStateIndex(TInt aWgId) const |
|
586 { |
|
587 TInt count = iWgStates->Count(); |
|
588 for (TInt ii=0; ii<count; ii++) |
|
589 { |
|
590 if (iWgStates->At(ii).WgId() == aWgId) |
|
591 { |
|
592 return ii; |
|
593 } |
|
594 } |
|
595 return KErrNotFound; |
|
596 } |
|
597 |
|
598 CEikSgcServer::CWgIds* CEikSgcServer::CreateWgIdListLC() const |
|
599 { |
|
600 CWgIds* wgIds = new(ELeave) CWgIds(1); |
|
601 CleanupStack::PushL(wgIds); |
|
602 iWs.WindowGroupList(wgIds); |
|
603 return wgIds; |
|
604 } |
|
605 |
|
606 void CEikSgcServer::ReOrderWgStatesL(CWgIds* aWgIds) |
|
607 { |
|
608 CWgStates* newStates = new(ELeave) CWgStates(KWgStatesGranularity); |
|
609 CleanupStack::PushL(newStates); |
|
610 TInt count = aWgIds->Count(); |
|
611 newStates->ResizeL(count); |
|
612 for (TInt ii=0; ii<count; ii++) |
|
613 { |
|
614 newStates->At(ii) = GetWgStateL(aWgIds->At(ii)); |
|
615 } |
|
616 CleanupStack::Pop(newStates); |
|
617 delete iWgStates; |
|
618 iWgStates = newStates; |
|
619 } |
|
620 |
|
621 void CEikSgcServer::SetStatusPaneShapeAndFlagsL(TInt aSpIndex) |
|
622 { |
|
623 if (aSpIndex == KErrNotFound) |
|
624 { |
|
625 return; |
|
626 } |
|
627 TWgState& topState = iWgStates->At(aSpIndex); |
|
628 |
|
629 TInt layout = topState.SpLayout(); |
|
630 if (iLayout != layout) |
|
631 { |
|
632 iSp->SwitchLayoutL(layout); |
|
633 iLayout = layout; |
|
634 } |
|
635 |
|
636 TInt flags = topState.SpFlags(); |
|
637 if (iFlags != flags) |
|
638 { |
|
639 iSp->SetFlags(flags); |
|
640 iFlags = flags; |
|
641 } |
|
642 } |
|
643 |
|
644 #ifndef TFX_USE_WCHANGE_EVENT |
|
645 void CEikSgcServer::ActivateEffectL() |
|
646 { |
|
647 if(iWinChange == NULL) |
|
648 { |
|
649 return; // nobody there |
|
650 } |
|
651 |
|
652 // CWindowChangeMonitor::TWinGroupEvent event = |
|
653 // iWinChange->WinGroupEvent(); |
|
654 |
|
655 const TInt index = FocusWgIndex(); |
|
656 //WgStateIndex(iWinChange-> GetFocusWg()); |
|
657 |
|
658 const TInt focusWgIndex = index < 0 ? 0 : index; |
|
659 |
|
660 const TInt count = iWgStates->Count(); |
|
661 |
|
662 for (TInt i = focusWgIndex; i < count; i++) |
|
663 { |
|
664 const TWgState& state = iWgStates->At(focusWgIndex); |
|
665 const TInt wgId = state.WgId(); |
|
666 |
|
667 if(state.UnderstandsPartialForeground()) |
|
668 { |
|
669 if(wgId != iFirstFullScreenWg) |
|
670 { |
|
671 iWinChange->WgChangeL(wgId); |
|
672 } |
|
673 |
|
674 // Note that exits also for non fullscreen (unlike SetPartialForegroundStatusesL). |
|
675 return; |
|
676 } |
|
677 } |
|
678 } |
|
679 #endif |
|
680 |
|
681 void CEikSgcServer::SetPartialForegroundStatusesL() |
|
682 { |
|
683 TInt count = iWgStates->Count(); |
|
684 TInt ii; |
|
685 TBool partialFg = EFalse; |
|
686 for (ii = FocusWgIndex(); ii < count; ii++) |
|
687 { |
|
688 TWgState& state = iWgStates->At(ii); |
|
689 if (state.UnderstandsPartialForeground()) |
|
690 { |
|
691 if (partialFg) |
|
692 { |
|
693 SetWgPartialFg(state); |
|
694 } |
|
695 if (!state.IsFullScreen()) |
|
696 { |
|
697 partialFg = ETrue; |
|
698 } |
|
699 else |
|
700 { |
|
701 // Notify first full-screen app that it is topmost application though does not |
|
702 // have kb focus. |
|
703 if (iFirstFullScreenWg != iWgStates->At(ii).WgId() ) |
|
704 { |
|
705 // same event instance will be recycled for both of events... |
|
706 TWsEvent event; |
|
707 event.SetTimeNow(); |
|
708 |
|
709 if (iFirstFullScreenWg) // notify old that it has lost its focus |
|
710 { |
|
711 event.SetType(KAknFullOrPartialForegroundLost); |
|
712 iWs.SendEventToWindowGroup(iFirstFullScreenWg, event); |
|
713 } |
|
714 |
|
715 iFirstFullScreenWg = iWgStates->At(ii).WgId(); |
|
716 event.SetType(KAknFullOrPartialForegroundGained); |
|
717 iWs.SendEventToWindowGroup(iFirstFullScreenWg, event); |
|
718 } |
|
719 break; |
|
720 } |
|
721 } |
|
722 } |
|
723 for (++ii; ii<count; ii++) |
|
724 { |
|
725 TWgState& state = iWgStates->At(ii); |
|
726 if (state.UnderstandsPartialForeground()) |
|
727 { |
|
728 ClearWgPartialFg(state); |
|
729 } |
|
730 } |
|
731 |
|
732 #ifndef TFX_USE_WCHANGE_EVENT |
|
733 if(iWinChange != NULL) |
|
734 { |
|
735 iWinChange->SetWgL(iFirstFullScreenWg); |
|
736 } |
|
737 #endif |
|
738 } |
|
739 |
|
740 void CEikSgcServer::PostChangeRecalcL() |
|
741 { |
|
742 #ifndef TFX_USE_WCHANGE_EVENT |
|
743 ActivateEffectL(); |
|
744 #endif |
|
745 |
|
746 TInt topSp = TopSpIndex(); |
|
747 SetLayoutL(topSp); |
|
748 SetStatusPaneShapeAndFlagsL(topSp); |
|
749 SetPartialForegroundStatusesL(); |
|
750 } |
|
751 |
|
752 TBool CEikSgcServer::TestWgListOrderOk(CWgIds* aWgIds) const |
|
753 { |
|
754 TInt count = aWgIds->Count(); |
|
755 if (count != iWgStates->Count()) |
|
756 { |
|
757 return EFalse; |
|
758 } |
|
759 for (TInt ii = 0; ii < count; ii++) |
|
760 { |
|
761 if (aWgIds->At(ii) != iWgStates->At(ii).WgId()) |
|
762 { |
|
763 return EFalse; |
|
764 } |
|
765 } |
|
766 return ETrue; |
|
767 } |
|
768 |
|
769 TInt CEikSgcServer::FocusWgIndex() const |
|
770 { |
|
771 TInt index = WgStateIndex(iWs.GetFocusWindowGroup()); |
|
772 if (index == KErrNotFound) |
|
773 { |
|
774 index = 0; |
|
775 } |
|
776 return index; |
|
777 } |
|
778 |
|
779 void CEikSgcServer::SetWgPartialFg(TWgState& aWgState) |
|
780 { |
|
781 if (!aWgState.IsPartialForeground()) |
|
782 { |
|
783 aWgState.SetPartialForeground(ETrue); |
|
784 } |
|
785 } |
|
786 |
|
787 void CEikSgcServer::ClearWgPartialFg(TWgState& aWgState) |
|
788 { |
|
789 if (aWgState.IsPartialForeground()) |
|
790 { |
|
791 aWgState.SetPartialForeground(EFalse); |
|
792 } |
|
793 } |
|
794 |
|
795 void CEikSgcServer::SetStatusPane(CEikServStatusPane* aSp) |
|
796 { |
|
797 ASSERT(aSp); |
|
798 iSp = aSp; |
|
799 iSpWg = aSp->WindowGroup(); |
|
800 } |
|
801 |
|
802 TInt CEikSgcServer::TopSpIndex(TInt aAfter) const |
|
803 { |
|
804 TInt count = iWgStates->Count(); |
|
805 for (TInt topSp=aAfter+1; topSp<count; topSp++) |
|
806 { |
|
807 if (iWgStates->At(topSp).SpLayout()) |
|
808 { |
|
809 return topSp; |
|
810 } |
|
811 } |
|
812 return KErrNotFound; |
|
813 } |
|
814 |
|
815 void CEikSgcServer::PrepareForAppExitL(TInt aWgId) |
|
816 { |
|
817 TInt topSp = TopSpIndex(); |
|
818 if (topSp != KErrNotFound) |
|
819 { |
|
820 TWgState& topState = iWgStates->At(topSp); |
|
821 if (topState.WgId() == aWgId) |
|
822 { |
|
823 TInt focusWg = FocusWgIndex(); |
|
824 if (focusWg != KErrNotFound && iWgStates->At(focusWg).IsPartialForeground()) |
|
825 { // we trust that wg order is valid at this point. |
|
826 if ( focusWg < iWgStates->Count()-1 ) |
|
827 { |
|
828 TWsEvent event; |
|
829 event.SetType(EEventUser); |
|
830 *(TApaSystemEvent*)(event.EventData())=EApaSystemEventBroughtToForeground; |
|
831 event.SetTimeNow(); |
|
832 iWs.SendEventToWindowGroup(iWgStates->At(focusWg+1).WgId(), event); |
|
833 } |
|
834 } |
|
835 |
|
836 // remove the status pane from the exiting wg |
|
837 topState.SetSpLayout(0); |
|
838 |
|
839 // Set the status pane to the shape for the app below |
|
840 topSp = TopSpIndex(topSp); |
|
841 SetLayoutL(topSp); |
|
842 SetStatusPaneShapeAndFlagsL(topSp); |
|
843 if (iSp) |
|
844 { |
|
845 iSp->PrepareForAppExit(); |
|
846 } |
|
847 } |
|
848 } |
|
849 } |
|
850 |
|
851 #define FADE_COLOR_17 1 |
|
852 //#define FADE_COLOR_TEXT 1 |
|
853 |
|
854 inline TUint8 GetColorIntensity(TUint32 aColor) |
|
855 { |
|
856 // Separate R, G, B |
|
857 register TUint32 r = (aColor >> 16) & 0xFF; |
|
858 register TUint32 g = (aColor >> 8) & 0xFF; |
|
859 register TUint32 b = (aColor) & 0xFF; |
|
860 |
|
861 // Calculate and return intensity |
|
862 return TUint8( (r*306 + g*601 + b*117) >> 10 ); |
|
863 } |
|
864 |
|
865 void CEikSgcServer::FadeColorGenerationL() |
|
866 { |
|
867 MAknsSkinInstance *skin = AknsUtils::SkinInstance(); |
|
868 bool b = false; |
|
869 #if FADE_COLOR_17 |
|
870 TAknsItemID skinid = KAknsIIDQsnOtherColors; |
|
871 TRgb colorrgb; |
|
872 TInt err = AknsUtils::GetCachedColor(skin, colorrgb, skinid, 19-1); |
|
873 if (err != KErrNone) |
|
874 { |
|
875 colorrgb = TRgb(255,255,255,0); |
|
876 |
|
877 CFbsBitmap *bitmap=NULL, *mask=NULL; |
|
878 TAknsItemID skinid = KAknsIIDQsnFrPopupCenter ; |
|
879 TRAP(err, AknsUtils::CreateIconL(skin, skinid, bitmap, mask, _L(""), -1, -1)); |
|
880 if (err == KErrNone) |
|
881 { |
|
882 TSize size(30,30); |
|
883 AknIconUtils::DisableCompression(bitmap); |
|
884 AknIconUtils::SetSize(bitmap, size, EAspectRatioNotPreserved); |
|
885 TPoint point(15,15); |
|
886 |
|
887 //TBuf8<4> buf; |
|
888 //bitmap->GetScanLine(buf, point, 1, bitmap->DisplayMode()); |
|
889 //colorrgb = TRgb(buf[3], buf[2], buf[1], buf[0]); |
|
890 |
|
891 //colorrgb.SetAlpha(buf[0]); |
|
892 //colorrgb.SetBlue(buf[1]); |
|
893 //colorrgb.SetGreen(buf[2]); |
|
894 //colorrgb.SetRed(buf[3]); |
|
895 bitmap->GetPixel(colorrgb, point); |
|
896 |
|
897 delete bitmap; |
|
898 delete mask; |
|
899 b=true; |
|
900 } |
|
901 } |
|
902 TRgb blackmap, whitemap; |
|
903 TInt err1 = AknsUtils::GetCachedColor(skin, blackmap, skinid, 17-1); |
|
904 TInt err2 = AknsUtils::GetCachedColor(skin, whitemap, skinid, 18-1); |
|
905 |
|
906 if (err1 != KErrNone) blackmap = TRgb(0,0,0,0); |
|
907 if (err2 != KErrNone) whitemap = TRgb(255,255,255,0); |
|
908 |
|
909 TInt blackcolor = (blackmap.Red()<<16) + (blackmap.Green()<<8) + blackmap.Blue(); |
|
910 TInt whitecolor = (whitemap.Red()<<16) + (whitemap.Green()<<8) + whitemap.Blue(); |
|
911 |
|
912 TInt blackmapint = GetColorIntensity(blackcolor); |
|
913 TInt whitemapint = GetColorIntensity(whitecolor); |
|
914 |
|
915 #endif |
|
916 |
|
917 #if FADE_COLOR_TEXT |
|
918 TAknsItemID skinid = KAknsIIDQsnOtherColors; |
|
919 TRgb colorrgb; |
|
920 TInt err = AknsUtils::GetCachedColor(skin, colorrgb, skinid, 17); |
|
921 if (err != KErrNone) |
|
922 { |
|
923 |
|
924 TAknsItemID skinid = KAknsIIDQsnTextColors ; |
|
925 TInt err = AknsUtils::GetCachedColor(skin, colorrgb, skinid, EAknsCIQsnTextColorsCG19 ); |
|
926 } |
|
927 TInt blackmapint = 0; |
|
928 TInt whitemapint = 255; |
|
929 #endif |
|
930 |
|
931 TInt color = (colorrgb.Red()<<16) + (colorrgb.Green()<<8) + colorrgb.Blue(); |
|
932 |
|
933 if (b) |
|
934 { |
|
935 TInt intensity = GetColorIntensity(color); |
|
936 if (intensity < 127) |
|
937 { // background color dark |
|
938 blackmapint = 0; |
|
939 whitemapint = 64; |
|
940 color = 0xffffff; |
|
941 } |
|
942 else |
|
943 { |
|
944 blackmapint = 192; |
|
945 whitemapint = 255; |
|
946 color = 0xffffff; |
|
947 } |
|
948 } |
|
949 RProperty::Set(KPSUidAvkonInternal, KAknFadeBlackMapHandle, blackmapint); |
|
950 RProperty::Set(KPSUidAvkonInternal, KAknFadeWhiteMapHandle, whitemapint); |
|
951 RProperty::Set(KPSUidAvkonInternal, KAknFadeColorHandle, color); |
|
952 |
|
953 } |
|
954 |
|
955 void CEikSgcServer::FadeBitmapGenerationL() |
|
956 { |
|
957 #if FADE_BITMAP |
|
958 // |
|
959 // Generates bitmap and mask for fade wserv plugin and |
|
960 // publishes them in publish&subscribe. |
|
961 // |
|
962 delete iFadeBitmap; |
|
963 delete iFadeMask; |
|
964 iFadeBitmap = NULL; |
|
965 iFadeMask = NULL; |
|
966 |
|
967 MAknsSkinInstance *skin = AknsUtils::SkinInstance(); |
|
968 |
|
969 TInt err= KErrNone; |
|
970 if (!Layout_Meta_Data::IsLandscapeOrientation()) |
|
971 { |
|
972 TAknsItemID skinid = KAknsIIDQgnGrafBgDimmingPrt; // TODO |
|
973 TRAP(err, AknsUtils::CreateIconL(skin, skinid, iFadeBitmap, iFadeMask, _L(""), -1, -1)); |
|
974 } |
|
975 else |
|
976 { |
|
977 TAknsItemID skinid = KAknsIIDQgnGrafBgDimmingLsc; // TODO |
|
978 TRAP(err, AknsUtils::CreateIconL(skin, skinid, iFadeBitmap, iFadeMask, _L(""), -1, -1)); |
|
979 } |
|
980 if (err != KErrNone) |
|
981 { |
|
982 TAknsItemID skinid = KAknsIIDQgnGrafBgDimming ; // TODO |
|
983 TRAP(err, AknsUtils::CreateIconL(skin, skinid, iFadeBitmap, iFadeMask, _L(""), -1, -1)); |
|
984 } |
|
985 |
|
986 if (err == KErrNone) |
|
987 { // found from skins |
|
988 |
|
989 TRect rect = TRect(0,0,0,0); |
|
990 TAknLayoutRect r; |
|
991 r.LayoutRect(rect, AknLayoutScalable_Avkon::Screen().LayoutLine()); |
|
992 TSize size = r.Rect().Size(); |
|
993 |
|
994 AknIconUtils::SetSize(iFadeBitmap, size, EAspectRatioNotPreserved); |
|
995 |
|
996 |
|
997 TInt bitmaphandle = iFadeBitmap->Handle(); |
|
998 TInt maskhandle = iFadeMask->Handle(); |
|
999 RProperty::Set(KPSUidAvkonInternal, KAknFadeBitmapHandle, bitmaphandle); |
|
1000 RProperty::Set(KPSUidAvkonInternal, KAknFadeMaskHandle, maskhandle); |
|
1001 } |
|
1002 #endif |
|
1003 } |
|
1004 void CEikSgcServer::SetLayoutL(TInt aSpIndex) |
|
1005 { |
|
1006 if (aSpIndex == KErrNotFound) |
|
1007 { |
|
1008 return; |
|
1009 } |
|
1010 |
|
1011 TWgState& topState = iWgStates->At(aSpIndex); |
|
1012 |
|
1013 CEikonEnv* eikEnv = CEikonEnv::Static(); |
|
1014 |
|
1015 CAknLayoutConfig::TScreenMode mode = CAknSgcClient::CalculateScreenMode( |
|
1016 ETrue, |
|
1017 topState.IsOrientationSpecified(), |
|
1018 topState.IsOrientationLandscape(), |
|
1019 topState.AppScreenMode()); |
|
1020 |
|
1021 TInt modeIndex = mode.ModeNumber(); |
|
1022 TBool blank = iLastScreenModeSet != -1; |
|
1023 if (modeIndex != iLastScreenModeSet) |
|
1024 { |
|
1025 |
|
1026 // Touch compatibility mode. Disable transition effects if compa-mode |
|
1027 // application becomes foreground. Restore back in opposite case. |
|
1028 if (iTouchCompaModeIf) |
|
1029 { |
|
1030 // Disable or restore transition |
|
1031 iTouchCompaModeIf->DisableTransEffects( |
|
1032 iTouchCompaScreenMode == modeIndex); |
|
1033 } |
|
1034 |
|
1035 TBool tfxOn = EFalse; |
|
1036 #ifdef RD_UI_TRANSITION_EFFECTS_LAYOUT_SWITCH |
|
1037 tfxOn = CAknTransitionUtils::TransitionsEnabled( |
|
1038 AknTransEffect::ELayoutswitchTransitionsOff ); |
|
1039 if ( tfxOn ) |
|
1040 { |
|
1041 iSetLayoutBlankStep = ESetLayoutBlankAfterScreenRotate; |
|
1042 } |
|
1043 else |
|
1044 { |
|
1045 iSetLayoutBlankStep = ESetLayoutBlankBeforeLayoutLoad; |
|
1046 } |
|
1047 #endif |
|
1048 |
|
1049 if (!tfxOn) |
|
1050 eikEnv->WsSession().ClearAllRedrawStores(); |
|
1051 |
|
1052 // If AknNfySrv or EikSrv is displaying a global note, |
|
1053 // the screen blanker is allowed to stay on until it times |
|
1054 // out (like when AknCapSrv is displaying a note). |
|
1055 TInt blankCnt = 1; |
|
1056 if (IsGlobalNoteForeground()) |
|
1057 { |
|
1058 // For some reason, AknNfySrv and EikSrv unblank twice on target hardware. |
|
1059 // therefore blank is done 3 times to allow it to remain on until timeout. |
|
1060 blankCnt += 2; |
|
1061 } |
|
1062 |
|
1063 SetLayoutBlankScreenL(blank, ESetLayoutBlankBeforeLayoutLoad, |
|
1064 blankCnt); |
|
1065 |
|
1066 const TAknLayoutConfigScreenMode& modeRef = (const TAknLayoutConfigScreenMode&) mode; |
|
1067 TBool newLayoutLoaded = CAknEnv::Static()->LoadAknLayoutL(modeRef); |
|
1068 |
|
1069 FadeBitmapGenerationL(); |
|
1070 FadeColorGenerationL(); |
|
1071 SetLayoutBlankScreenL(blank, ESetLayoutBlankBetweenLayoutLoadAndScreenRotate); |
|
1072 |
|
1073 if (tfxOn) |
|
1074 eikEnv->WsSession().ClearAllRedrawStores(); |
|
1075 |
|
1076 // if layout change is preemptive for app change, move the app here |
|
1077 DoMoveApp(); |
|
1078 |
|
1079 // Set wserv screen mode |
|
1080 iLastScreenModeSet = modeIndex; |
|
1081 eikEnv->ScreenDevice()->SetScreenMode(modeIndex); |
|
1082 |
|
1083 SetLayoutBlankScreenL(blank, ESetLayoutBlankAfterScreenRotate, |
|
1084 blankCnt); |
|
1085 |
|
1086 // Set legacy mode in eiksrv app UI |
|
1087 iAvkonAppUiBase->SetLayoutAwareApp(!topState.IsLegacyLayout()); |
|
1088 |
|
1089 // Start callback for handling new layout |
|
1090 if (newLayoutLoaded) |
|
1091 { |
|
1092 // Swap the screen blanker to update the foreground app's layout |
|
1093 if (blank && iSetLayoutBlankStep < ESetLayoutBlankAfterScreenRotate) |
|
1094 { |
|
1095 iAknCapAppServerAppUi->SwapLayoutSwitchBlankScreenL(); |
|
1096 } |
|
1097 |
|
1098 CAknAppUi* appUi = static_cast<CAknAppUi*>(eikEnv->EikAppUi()); |
|
1099 if (appUi->IsForeground()) |
|
1100 { |
|
1101 for (; appUi; appUi = static_cast<CAknAppUi*>(appUi->ContainerAppUi())) |
|
1102 { |
|
1103 appUi->ReportResourceChangedToAppL(KEikDynamicLayoutVariantSwitch); |
|
1104 } |
|
1105 } |
|
1106 |
|
1107 if (iLayoutChangeCallBack) |
|
1108 { |
|
1109 // Restart the app delay callback timer if another layout change has happened |
|
1110 // before it triggers. |
|
1111 iLayoutChangeCallBack->RestartTimerL(); |
|
1112 } |
|
1113 else |
|
1114 { |
|
1115 iLayoutChangeCallBack = new(ELeave) CLayoutChangeCallBack(this); |
|
1116 iLayoutChangeCallBack->ConstructL(); |
|
1117 } |
|
1118 |
|
1119 // stop any existing timer to unblank the screen, iLayoutChangeCallBack will restart it |
|
1120 delete iRemoveBlankCallBack; |
|
1121 iRemoveBlankCallBack = NULL; |
|
1122 } |
|
1123 else |
|
1124 { |
|
1125 if (!iLayoutChangeCallBack && blank) |
|
1126 { |
|
1127 // The callback will not remove the screen blanker, |
|
1128 // so remove it now. |
|
1129 iBlankCount--; |
|
1130 iAknCapAppServerAppUi->BlankScreenL(EFalse); |
|
1131 } |
|
1132 } |
|
1133 } |
|
1134 } |
|
1135 |
|
1136 void CEikSgcServer::SetLayoutBlankScreenL(TBool aBlank, TInt aStep) |
|
1137 { |
|
1138 // Use a screen blanker to hide the screen change |
|
1139 if (aBlank && aStep == iSetLayoutBlankStep) |
|
1140 { |
|
1141 // blank the screen and keep track of how many times it's been blanked |
|
1142 iBlankCount++; |
|
1143 iAknCapAppServerAppUi->BlankScreenL(ETrue, ETrue); |
|
1144 } |
|
1145 } |
|
1146 |
|
1147 void CEikSgcServer::HandleLayoutChangeCallBackL() |
|
1148 { |
|
1149 // delete the active object |
|
1150 delete iLayoutChangeCallBack; |
|
1151 iLayoutChangeCallBack = NULL; |
|
1152 |
|
1153 CEikonEnv* eikEnv = CEikonEnv::Static(); |
|
1154 |
|
1155 // Report the layout change to the UI controls |
|
1156 for (CEikAppUi* appUi = eikEnv->EikAppUi(); appUi; appUi = appUi->ContainerAppUi()) |
|
1157 { |
|
1158 appUi->ReportResourceChangedToAppL(KEikDynamicLayoutVariantSwitch); |
|
1159 } |
|
1160 |
|
1161 // if visible tasklist must be updated during layout change event |
|
1162 iAknCapAppServerAppUi->UpdateTaskListL( ETrue ); |
|
1163 |
|
1164 // Remove any remaining screen blanker after a delay. |
|
1165 // Normally the foreground app will have removed all blanking |
|
1166 // before this function triggers. This is really just a backup |
|
1167 // in-case the app is behaving badly, or if some unfortuante |
|
1168 // timing has caused this function to trigger before the foreground app |
|
1169 // finished its redraw. The delay should give the foreground app |
|
1170 // sufficient time. |
|
1171 iRemoveBlankCount += iBlankCount; |
|
1172 iBlankCount = 0; |
|
1173 delete iRemoveBlankCallBack; |
|
1174 iRemoveBlankCallBack = NULL; |
|
1175 iRemoveBlankCallBack = CPeriodic::NewL(CActive::EPriorityLow); |
|
1176 |
|
1177 TInt removeBlankDelay = CAknEnv::Static()->TransparencyEnabled() ? |
|
1178 KRemoveBlankDelayTransparency : KRemoveBlankDelay; |
|
1179 |
|
1180 if(iAknCapAppServerAppUi->IsShortTimeGlobalNoteDisplaying()) |
|
1181 { |
|
1182 removeBlankDelay = KRemoveBlankDelay; |
|
1183 } |
|
1184 |
|
1185 iRemoveBlankCallBack->Start( |
|
1186 removeBlankDelay, |
|
1187 removeBlankDelay, |
|
1188 TCallBack(RemoveBlankCallBack, this)); |
|
1189 } |
|
1190 |
|
1191 void CEikSgcServer::RelinquishPriorityToForegroundAppL(const RMessage2& aMessage) |
|
1192 { |
|
1193 // get the client thread |
|
1194 SRelinquishedThread rel; |
|
1195 aMessage.ClientL(rel.iThread); |
|
1196 CleanupClosePushL(rel.iThread); |
|
1197 rel.iId = rel.iThread.Id(); |
|
1198 rel.iPriority = rel.iThread.ProcessPriority(); |
|
1199 |
|
1200 // reset the callback timer, ensure that failure does not stop existing timer |
|
1201 CPeriodic* newCallBack = CPeriodic::NewL(CActive::EPriorityStandard); |
|
1202 delete iRelinquishedThreadCallBack; |
|
1203 iRelinquishedThreadCallBack = newCallBack; |
|
1204 |
|
1205 iRelinquishedThreadCallBack->Start( |
|
1206 KRestoreThreadPriorityDelay, |
|
1207 KRestoreThreadPriorityDelay, |
|
1208 TCallBack(RestoreThreadPriorities, this)); |
|
1209 |
|
1210 // look for an existing thread |
|
1211 TInt count = iRelinquishedThreads.Count(); |
|
1212 TInt pos; |
|
1213 for ( pos = 0; pos < count; pos++ ) |
|
1214 { |
|
1215 if (iRelinquishedThreads[pos].iId == rel.iId) |
|
1216 { |
|
1217 break; |
|
1218 } |
|
1219 } |
|
1220 |
|
1221 if (pos<count) |
|
1222 { |
|
1223 // thread is already recorded. Make sure it's background and stop |
|
1224 rel.iThread.SetProcessPriority(EPriorityBackground); |
|
1225 CleanupStack::PopAndDestroy(&rel.iThread); |
|
1226 } |
|
1227 else |
|
1228 { |
|
1229 // add thread to array |
|
1230 iRelinquishedThreads.AppendL(rel); |
|
1231 CleanupStack::Pop(&rel.iThread); |
|
1232 // set the thread to background priority when all recovery mechanisms are in place |
|
1233 rel.iThread.SetProcessPriority(EPriorityBackground); |
|
1234 } |
|
1235 |
|
1236 aMessage.Complete(KErrNone); |
|
1237 } |
|
1238 |
|
1239 TInt CEikSgcServer::RestoreThreadPriorities( TAny* aThis ) |
|
1240 { |
|
1241 static_cast<CEikSgcServer*>( aThis )->DoRestoreThreadPriorities(); |
|
1242 return EFalse; |
|
1243 } |
|
1244 |
|
1245 void CEikSgcServer::DoRestoreThreadPriorities() |
|
1246 { |
|
1247 delete iRelinquishedThreadCallBack; |
|
1248 iRelinquishedThreadCallBack = NULL; |
|
1249 TInt count = iRelinquishedThreads.Count(); |
|
1250 for (TInt ii=0; ii<count; ii++) |
|
1251 { |
|
1252 SRelinquishedThread& rel = iRelinquishedThreads[ii]; |
|
1253 rel.iThread.SetProcessPriority(rel.iPriority); |
|
1254 rel.iThread.Close(); |
|
1255 } |
|
1256 iRelinquishedThreads.Reset(); |
|
1257 } |
|
1258 |
|
1259 void CEikSgcServer::SetAknCapAppServerAppUi(CAknCapAppServerAppUi* aAknCapAppServerAppUi) |
|
1260 { |
|
1261 iAknCapAppServerAppUi = aAknCapAppServerAppUi; |
|
1262 } |
|
1263 |
|
1264 void CEikSgcServer::RotateScreenL() |
|
1265 { |
|
1266 // Toggle preferred orientation |
|
1267 TInt orientation; |
|
1268 TInt err = RProperty::Get(KPSUidUikon, KUikPreferredOrientation, orientation); |
|
1269 User::LeaveIfError(err); |
|
1270 |
|
1271 if (orientation == EPreferredOrientationNormal) |
|
1272 { |
|
1273 orientation = EPreferredOrientationAlternate; |
|
1274 } |
|
1275 else // alternate screen orientation |
|
1276 { |
|
1277 orientation = EPreferredOrientationNormal; |
|
1278 } |
|
1279 |
|
1280 err = RProperty::Set(KPSUidUikon, KUikPreferredOrientation, orientation); |
|
1281 User::LeaveIfError(err); |
|
1282 |
|
1283 CWsScreenDevice* device = CEikonEnv::Static()->ScreenDevice(); |
|
1284 TInt screenMode = device->CurrentScreenMode(); |
|
1285 |
|
1286 CEikonEnv* eikEnv = CEikonEnv::Static(); |
|
1287 |
|
1288 // Update the setting cache and get SGCS to process the screen mode |
|
1289 // change, this may broadcast a screen device change to the apps, |
|
1290 // to inform them of the update |
|
1291 CAknEnv::Static()->SettingCache().Update( KAknHardwareLayoutSwitch ); |
|
1292 HandleWindowGroupParamChangeL( |
|
1293 eikEnv->RootWin().Identifier(), |
|
1294 0, |
|
1295 0, |
|
1296 0, |
|
1297 KAknScreenModeUnset ); |
|
1298 |
|
1299 if (screenMode == device->CurrentScreenMode()) |
|
1300 { |
|
1301 // Apps will not have received a screen device changed event |
|
1302 // so send a KAknHardwareLayoutSwitch to the apps to ensure |
|
1303 // they get to know about the key |
|
1304 TWsEvent event; |
|
1305 event.SetType(KAknHardwareLayoutSwitch); |
|
1306 event.SetHandle(0); |
|
1307 eikEnv->WsSession().SendEventToAllWindowGroups( 0, event ); |
|
1308 } |
|
1309 } |
|
1310 |
|
1311 void CEikSgcServer::UpdateNotificationsInIdleAllowedKey() |
|
1312 { |
|
1313 // First, get screensaver window group identifier. |
|
1314 TApaTaskList taskList(CEikonEnv::Static()->WsSession()); |
|
1315 const TApaTask screensaverTask = taskList.FindApp(KScreensaverAppUid); |
|
1316 const TInt screensaverWgId = screensaverTask.WgId(); |
|
1317 |
|
1318 // Get also idle window group identifier. |
|
1319 TVwsViewId idleView; |
|
1320 if (AknDef::GetPhoneIdleViewId(idleView) != KErrNone) |
|
1321 { |
|
1322 return; |
|
1323 } |
|
1324 |
|
1325 const TApaTask idleTask = taskList.FindApp(idleView.iAppUid); |
|
1326 const TInt idleWgId = idleTask.WgId(); |
|
1327 |
|
1328 // Then go through window groups skipping partial apps and screensaver - |
|
1329 // check if idleWgId follows. |
|
1330 TBool result = EFalse; |
|
1331 TBool found = EFalse; |
|
1332 const TInt wgCount = iWgStates->Count(); |
|
1333 TInt ii = FocusWgIndex(); |
|
1334 |
|
1335 LOGTEXT0("======================================"); |
|
1336 LOGTEXT1("Window groups: %d", wgCount); |
|
1337 LOGTEXT1("Idle wg id: %d", idleWgId); |
|
1338 LOGTEXT1("Screensaver wg id: %d", screensaverWgId); |
|
1339 LOGTEXT1("Focus window group: %d", ii); |
|
1340 LOGTEXT0("======================================"); |
|
1341 |
|
1342 // Loops window groups from top to bottom, starting from focus window group. |
|
1343 // (Index 0 contains the foreground window group.) |
|
1344 while (ii < wgCount && !found) |
|
1345 { |
|
1346 const TWgState& state = iWgStates->At(ii); |
|
1347 const TInt currentWgId = state.WgId(); |
|
1348 |
|
1349 LOGTEXT0("\n"); |
|
1350 LOGTEXT1(" Window group id: %d", currentWgId); |
|
1351 LOGTEXT1(" UnderstandsPartialForeground: %d", state.UnderstandsPartialForeground()); |
|
1352 LOGTEXT1(" IsFullScreen: %d", state.IsFullScreen()); |
|
1353 |
|
1354 // Ignores non-application window groups (e.g. incall bubble), partial screen |
|
1355 // applications and screensaver. |
|
1356 if (state.UnderstandsPartialForeground() && |
|
1357 state.IsFullScreen() && |
|
1358 currentWgId != screensaverWgId) |
|
1359 { |
|
1360 // Check if current app is idle. |
|
1361 result = (idleWgId == currentWgId); |
|
1362 found = ETrue; |
|
1363 |
|
1364 LOGTEXT0("\n"); |
|
1365 LOGTEXT1("Window group found. Result: %d", result); |
|
1366 } |
|
1367 |
|
1368 ii++; |
|
1369 } |
|
1370 |
|
1371 // Update the P&S key only if the value has been changed. |
|
1372 if ((iNotificationsInIdleAllowed && !result) || (!iNotificationsInIdleAllowed && result)) |
|
1373 { |
|
1374 iNotificationsInIdleAllowed = result; |
|
1375 RProperty::Set(KPSUidAvkonDomain, KAknNotificationsInIdleAllowed, result); |
|
1376 } |
|
1377 } |
|
1378 |
|
1379 |
|
1380 TInt CEikSgcServer::RemoveBlankCallBack( TAny* aThis ) |
|
1381 { |
|
1382 static_cast<CEikSgcServer*>( aThis )->DoRemoveBlank(); |
|
1383 return EFalse; |
|
1384 } |
|
1385 |
|
1386 void CEikSgcServer::DoRemoveBlank() |
|
1387 { |
|
1388 // remove any remaining screen blanker |
|
1389 for (; iRemoveBlankCount>0; iRemoveBlankCount--) |
|
1390 { |
|
1391 TRAP_IGNORE( iAknCapAppServerAppUi->BlankScreenL( EFalse ) ); |
|
1392 } |
|
1393 |
|
1394 iRemoveBlankCount = 0; |
|
1395 |
|
1396 // readjust the status pane wg since we pushed it forward with the screen blanker |
|
1397 iLastTopSpWg = -1; |
|
1398 |
|
1399 delete iRemoveBlankCallBack; |
|
1400 iRemoveBlankCallBack = NULL; |
|
1401 } |
|
1402 |
|
1403 void CEikSgcServer::SetLayoutBlankScreenL(TBool aBlank, TInt aStep, |
|
1404 TInt aCnt) |
|
1405 { |
|
1406 while(aCnt--) |
|
1407 { |
|
1408 SetLayoutBlankScreenL(aBlank, aStep); |
|
1409 } |
|
1410 } |
|
1411 |
|
1412 // Check if AknNfySrv or EikSrv is displaying a global note |
|
1413 TBool CEikSgcServer::IsGlobalNoteForeground() |
|
1414 { |
|
1415 TBool isForeground = EFalse; |
|
1416 TThreadId threadId; |
|
1417 if (iWs.GetWindowGroupClientThreadId(iWs.GetFocusWindowGroup(), |
|
1418 threadId) == KErrNone) |
|
1419 { |
|
1420 RThread thread; |
|
1421 if (thread.Open(threadId) == KErrNone) |
|
1422 { |
|
1423 TSecureId secId = thread.SecureId(); |
|
1424 thread.Close(); |
|
1425 const TUid KEikSrvUid = {0x10003a4a}; |
|
1426 isForeground = |
|
1427 secId.iId == KCommonNotifierAppSrvUid.iUid || |
|
1428 secId.iId == KEikSrvUid.iUid; |
|
1429 } |
|
1430 } |
|
1431 return isForeground; |
|
1432 } |
|
1433 |
|
1434 void CEikSgcServer::MoveAppL(TInt aAppWindowGroupId, TSgcMoveAppToWhere aWhere) |
|
1435 { |
|
1436 CAknTaskList* taskList = CAknTaskList::NewLC(iWs); |
|
1437 |
|
1438 // step 1: Find root (going to foreground) or tip (going to background) of |
|
1439 // aAppWindowGroupId's window group chain |
|
1440 TInt wgId = aAppWindowGroupId; |
|
1441 for (TInt next=wgId; next;) |
|
1442 { |
|
1443 wgId = next; |
|
1444 next = (aWhere == ESgcMoveAppToForeground) ? |
|
1445 taskList->FindParentWgId(wgId) : |
|
1446 taskList->FindChildWgId(wgId); |
|
1447 } |
|
1448 |
|
1449 // step 2: Move whole window group chain |
|
1450 while (wgId) |
|
1451 { |
|
1452 // move the window group |
|
1453 TInt index = WgStateIndex(wgId); |
|
1454 if (index >= 0) |
|
1455 { |
|
1456 TWgState state = iWgStates->At(index); |
|
1457 iWgStates->Delete(index); |
|
1458 if (aWhere == ESgcMoveAppToForeground) |
|
1459 iWgStates->InsertL(0, state); |
|
1460 else |
|
1461 iWgStates->AppendL(state); |
|
1462 } |
|
1463 |
|
1464 // get the next window group in the chain |
|
1465 wgId = (aWhere == ESgcMoveAppToForeground) ? |
|
1466 taskList->FindChildWgId(wgId) : |
|
1467 taskList->FindParentWgId(wgId); |
|
1468 } |
|
1469 |
|
1470 CleanupStack::PopAndDestroy(taskList); |
|
1471 |
|
1472 // Step 3: do screen rotation and move app |
|
1473 iMoveAppWdId = aAppWindowGroupId; |
|
1474 iMoveAppWhere = aWhere; |
|
1475 |
|
1476 PostChangeRecalcL(); |
|
1477 |
|
1478 // if no layout switch occured, move app here |
|
1479 DoMoveApp(); |
|
1480 } |
|
1481 |
|
1482 void CEikSgcServer::DoMoveApp() |
|
1483 { |
|
1484 if (iMoveAppWdId) |
|
1485 { |
|
1486 TApaTask task(iWs); |
|
1487 task.SetWgId(iMoveAppWdId); |
|
1488 if (iMoveAppWhere == ESgcMoveAppToForeground) |
|
1489 task.BringToForeground(); |
|
1490 else |
|
1491 task.SendToBackground(); |
|
1492 iMoveAppWdId = 0; |
|
1493 } |
|
1494 } |
|
1495 |
|
1496 |
|
1497 // |
|
1498 // CAknSgcServerImpl |
|
1499 // |
|
1500 CAknSgcServerImpl::CAknSgcServerImpl(CEikSgcServer* aServer) |
|
1501 : iServer(aServer) |
|
1502 { |
|
1503 } |
|
1504 |
|
1505 void CAknSgcServerImpl::MoveApp(TInt aAppWindowGroupId, TSgcMoveAppToWhere aWhere) |
|
1506 { |
|
1507 TRAP_IGNORE(iServer->MoveAppL(aAppWindowGroupId, aWhere)); |
|
1508 } |
|
1509 |
|
1510 // End of file |