|
1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <apgtask.h> |
|
17 #include <apgwgnam.h> |
|
18 |
|
19 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
20 #include "vwsinternal.h" |
|
21 #include "vwsdefpartner.h" |
|
22 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS |
|
23 |
|
24 #include "VWSERVER.H" |
|
25 #include "VWSSESSN.H" |
|
26 #include "VWSEVENT.H" |
|
27 #include "VWSWEVNT.H" |
|
28 #include "VWSADDOB.H" |
|
29 #include "VWSPRIV.H" |
|
30 #include "VWSDEBUG.H" |
|
31 #include "vwspatchdata.h" |
|
32 |
|
33 |
|
34 #include <barsc2.h> |
|
35 #include <barsread2.h> |
|
36 #include <f32file.h> |
|
37 #include <u32hal.h> |
|
38 |
|
39 // |
|
40 // Constants. |
|
41 // |
|
42 |
|
43 const TInt KVwsSystemDefaultViewArrayGranularity=2; |
|
44 const TInt KDefaultClientRequestTimeOutDuration=1000000; |
|
45 const TInt KDefaultServerEventTimeOutDuration=10000000; |
|
46 |
|
47 _LIT(KPriorityFilename,"Z:\\resource\\apps\\PrioritySet.rsc"); |
|
48 |
|
49 |
|
50 const TUint8 KPolicyElementSID = 0; |
|
51 const TUint8 KPolicyPowerMgmt = 1; |
|
52 |
|
53 const TInt KEiksrvsSid=0x10003a4a; |
|
54 |
|
55 const TUint KRangeCount = 5; |
|
56 |
|
57 const TInt KVwsServerRanges[KRangeCount] = |
|
58 { |
|
59 EFirstUnrestrictedOpcodeInVws, |
|
60 EFirstOpcodeNeedingCustomCheckInVws, |
|
61 EFirstOpcodeNeedingSecureIdInVws, |
|
62 EFirstOpCodeNeedingPowerMgmt, |
|
63 EVwsFirstUnusedOpcode, |
|
64 }; |
|
65 |
|
66 const TUint8 KElementsIndex[KRangeCount] = |
|
67 { |
|
68 CPolicyServer::EAlwaysPass, //Always passing no capability required [EFirstUnrestrictedOpcodeInVws-(EFirstOpcodeNeedingCustomCheckInVws-1)] |
|
69 CPolicyServer::ECustomCheck, //Requires Custom check [EFirstOpcodeNeedingCustomCheckInVws-(EFirstOpcodeNeedingSecureIdInVws-1)] |
|
70 KPolicyElementSID, //Requires SID to be of Eiksrvs ie.0x10003a4a [EFirstOpcodeNeedingSecureIdInVws-(EFirstOpCodeNeedingPowerMgmt-1)] |
|
71 KPolicyPowerMgmt, //Requires PowerMgmt capability [EFirstOpCodeNeedingPowerMgmt-(EVwsFirstUnusedOpcode-1)] |
|
72 CPolicyServer::ENotSupported, //Not Supported |
|
73 }; |
|
74 |
|
75 const CPolicyServer::TPolicyElement KPolicyElements[] = |
|
76 { |
|
77 {_INIT_SECURITY_POLICY_S0(KEiksrvsSid), CPolicyServer::EFailClient}, |
|
78 {_INIT_SECURITY_POLICY_C1(ECapabilityPowerMgmt), CPolicyServer::EFailClient} |
|
79 }; |
|
80 |
|
81 const CPolicyServer::TPolicy KVwsServerPolicy = |
|
82 { |
|
83 CPolicyServer::EAlwaysPass, |
|
84 KRangeCount, |
|
85 KVwsServerRanges, |
|
86 KElementsIndex, |
|
87 KPolicyElements |
|
88 }; |
|
89 |
|
90 // |
|
91 // CVwsServer. |
|
92 // |
|
93 |
|
94 #ifdef __DO_LOGGING__ |
|
95 CVwsServer::CVwsServer(TInt aPriority,MVwsAppStarter& aAppStarter) |
|
96 : CPolicyServer(aPriority,KVwsServerPolicy), |
|
97 iAppStarter(aAppStarter), |
|
98 iSystemDefaultViewIdArray(KVwsSystemDefaultViewArrayGranularity), |
|
99 iClientRequestTimeOut(KDefaultClientRequestTimeOutDuration), |
|
100 iServerEventTimeOut(KDefaultServerEventTimeOutDuration), |
|
101 iForegroundChangeWhileEventsOutstanding(EFalse), |
|
102 iIsServerEventTimeOutDisabled(0), |
|
103 iNoActivationRequests(0), |
|
104 iEnableServerBlankScreen(ETrue), |
|
105 iEnableBoostAppPriorityBeforePanic(KVwsBoostAppPriorityBeforePanic) |
|
106 { |
|
107 } |
|
108 #else |
|
109 CVwsServer::CVwsServer(TInt aPriority,MVwsAppStarter& aAppStarter) |
|
110 : CPolicyServer(aPriority,KVwsServerPolicy), |
|
111 iAppStarter(aAppStarter), |
|
112 iSystemDefaultViewIdArray(KVwsSystemDefaultViewArrayGranularity), |
|
113 iClientRequestTimeOut(KDefaultClientRequestTimeOutDuration), |
|
114 iServerEventTimeOut(KDefaultServerEventTimeOutDuration), |
|
115 iForegroundChangeWhileEventsOutstanding(EFalse), |
|
116 iIsServerEventTimeOutDisabled(0), |
|
117 iEnableServerBlankScreen(ETrue), |
|
118 iEnableBoostAppPriorityBeforePanic(KVwsBoostAppPriorityBeforePanic) |
|
119 { |
|
120 } |
|
121 #endif |
|
122 |
|
123 EXPORT_C CVwsServer* CVwsServer::NewL(MVwsAppStarter& aAppStarter) |
|
124 { |
|
125 CVwsServer *pS=new CVwsServer(CActive::EPriorityStandard,aAppStarter); |
|
126 __ASSERT_ALWAYS(pS!=NULL,PanicServer(EVwsServerCreate)); |
|
127 |
|
128 pS->ConstructL(); |
|
129 |
|
130 pS->StartL(KViewServerName); |
|
131 return pS; |
|
132 } |
|
133 |
|
134 CSession2* CVwsServer::NewSessionL(const TVersion &aVersion,const RMessage2& aMessage) const |
|
135 { |
|
136 // Check version supported. |
|
137 TVersion version(KVwsMajorVersionNumber,KVwsMinorVersionNumber,KVwsBuildVersionNumber); |
|
138 if (!User::QueryVersionSupported(version,aVersion)) |
|
139 { |
|
140 User::Leave(KErrNotSupported); |
|
141 } |
|
142 |
|
143 RThread thread; |
|
144 User::LeaveIfError(aMessage.Client(thread)); |
|
145 const TThreadId threadId(thread.Id()); |
|
146 thread.Close(); |
|
147 return CVwsSession::NewL(threadId,CONST_CAST(CVwsServer&,*this)); |
|
148 } |
|
149 |
|
150 |
|
151 EXPORT_C CVwsServer::~CVwsServer() |
|
152 { |
|
153 delete iWServSessionHandler; |
|
154 |
|
155 delete iEventQueue; |
|
156 #ifdef __DO_LOGGING__ |
|
157 CVwsLog::ShutdownLog(); |
|
158 #endif |
|
159 } |
|
160 |
|
161 void CVwsServer::ConstructL() |
|
162 { |
|
163 // required for handling intercepting window |
|
164 iWServSessionHandler=CVwsWServSessionHandler::NewL(*this); |
|
165 |
|
166 #ifdef __DO_LOGGING__ |
|
167 iEventQueue=new(ELeave) CVwsEventQueue(_L("Server Queue")); |
|
168 CVwsLog::StartLogL(); |
|
169 #else |
|
170 iEventQueue=new(ELeave) CVwsEventQueue; |
|
171 #endif |
|
172 RFs fs; |
|
173 iPrioritySet=CActive::EPriorityStandard; |
|
174 CleanupClosePushL(fs); |
|
175 if(fs.Connect()==KErrNone) |
|
176 { |
|
177 CResourceFile* file=NULL; |
|
178 TRAPD(err, file=CResourceFile::NewL(fs, KPriorityFilename, 0, 0)); |
|
179 if(err == KErrNone) |
|
180 { |
|
181 CleanupStack::PushL(file); |
|
182 RResourceReader reader; |
|
183 reader.OpenL(file, 2); |
|
184 CleanupClosePushL(reader); |
|
185 iPrioritySet=reader.ReadUint32L(); |
|
186 CleanupStack::PopAndDestroy(&reader); |
|
187 CleanupStack::PopAndDestroy(file); |
|
188 } |
|
189 fs.Close(); |
|
190 } |
|
191 |
|
192 CleanupStack::PopAndDestroy(&fs); |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 #ifdef __WINS__ |
|
199 // KVwsBoostAppPriorityBeforePanic is a Rom patchable constant, so need an emulator equivalent |
|
200 // if WINS then read value from epoc.ini requires licencees to set property in epoc.ini. |
|
201 // Usage: In epoc.ini patchdata_viewsrv_dll_KVwsBoostAppPriorityBeforePanic 1 |
|
202 |
|
203 TInt valueOfKVwsBoostAppPriorityBeforePanic = 0; |
|
204 if (UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"patchdata_viesrv_dll_KVwsBoostAppPriorityBeforePanic",&valueOfKVwsBoostAppPriorityBeforePanic) == KErrNone) |
|
205 { |
|
206 iEnableBoostAppPriorityBeforePanic = valueOfKVwsBoostAppPriorityBeforePanic; |
|
207 } |
|
208 #endif |
|
209 |
|
210 if (iEnableBoostAppPriorityBeforePanic) |
|
211 { |
|
212 CVwsStartupAware* startupAware = new(ELeave)CVwsStartupAware(*this); |
|
213 TInt err = startupAware->Start(); |
|
214 if (err != KErrNone) |
|
215 { |
|
216 HandleInitializationFinished(); |
|
217 delete startupAware; |
|
218 } |
|
219 } |
|
220 } |
|
221 |
|
222 CVwsStartupAware::CVwsStartupAware(CVwsServer& aServer) |
|
223 :CActive(CActive::EPriorityStandard),iServer(aServer) |
|
224 { |
|
225 CActiveScheduler::Add(this); |
|
226 } |
|
227 |
|
228 CVwsStartupAware::~CVwsStartupAware() |
|
229 { |
|
230 Cancel(); |
|
231 iStateAwareSession.Close(); |
|
232 } |
|
233 |
|
234 TInt CVwsStartupAware::Start() |
|
235 { |
|
236 TInt err = iStateAwareSession.Connect(KSM2UiServicesDomain3); |
|
237 if(iStateAwareSession.State().MainState() != ESsmNormal && err == KErrNone) |
|
238 { |
|
239 iStateAwareSession.RequestStateNotification(iStatus); |
|
240 SetActive(); |
|
241 } |
|
242 return err; |
|
243 } |
|
244 |
|
245 void CVwsStartupAware::RunL() |
|
246 { |
|
247 if (iStatus == KErrNone) |
|
248 { |
|
249 if (iStateAwareSession.State().MainState() == ESsmNormal) |
|
250 { |
|
251 iServer.HandleInitializationFinished(); //Bootup is complete now, allowing Viewsrv 11 panics to occur here onwards |
|
252 delete this; |
|
253 } |
|
254 else |
|
255 { |
|
256 iStateAwareSession.AcknowledgeAndRequestStateNotification(KErrNone, iStatus); |
|
257 SetActive(); |
|
258 } |
|
259 } |
|
260 } |
|
261 |
|
262 void CVwsStartupAware::DoCancel() |
|
263 { |
|
264 iStateAwareSession.RequestStateNotificationCancel(); |
|
265 } |
|
266 |
|
267 void CVwsServer::PanicClient(TInt aPanic) const |
|
268 { |
|
269 _LIT(KVwsSrvPanic, "ViewSrv"); |
|
270 User::Panic(KVwsSrvPanic,aPanic); |
|
271 } |
|
272 |
|
273 void CVwsServer::SetSystemDefaultViewL(TInt aMode,const TVwsViewId& aViewId) |
|
274 { |
|
275 __ASSERT_DEBUG(aMode>=0,PanicClient(EVwsInvalidScreenMode)); |
|
276 const TInt count = iSystemDefaultViewIdArray.Count(); |
|
277 |
|
278 if ((aMode>count) || (aMode<0)) |
|
279 { |
|
280 PanicClient(EVwsInvalidScreenMode); |
|
281 } |
|
282 else if (aMode < count) |
|
283 { |
|
284 iSystemDefaultViewIdArray.At(aMode) = aViewId; |
|
285 } |
|
286 else if (aMode == count) |
|
287 { |
|
288 iSystemDefaultViewIdArray.AppendL(aViewId); |
|
289 } |
|
290 } |
|
291 |
|
292 void CVwsServer::SetClientRequestTimeOut(const TTimeIntervalMicroSeconds32& aDuration) |
|
293 { |
|
294 iClientRequestTimeOut=aDuration; |
|
295 } |
|
296 |
|
297 void CVwsServer::SetServerEventTimeOut(const TTimeIntervalMicroSeconds32& aDuration) |
|
298 { |
|
299 iServerEventTimeOut=aDuration; |
|
300 } |
|
301 |
|
302 void CVwsServer::EnableServerEventTimeOut(TBool aEnable) |
|
303 { |
|
304 if (!aEnable) |
|
305 { |
|
306 iIsServerEventTimeOutDisabled++; |
|
307 } |
|
308 else if (iIsServerEventTimeOutDisabled) |
|
309 { |
|
310 iIsServerEventTimeOutDisabled--; |
|
311 } |
|
312 } |
|
313 |
|
314 void CVwsServer::EnableServerBlankScreen(TBool aEnable) |
|
315 { |
|
316 iEnableServerBlankScreen = aEnable; |
|
317 } |
|
318 |
|
319 void CVwsServer::GetSystemDefaultView(TVwsViewId& aViewId) |
|
320 { |
|
321 TInt mode=iWServSessionHandler->GetScreenMode(); |
|
322 aViewId = (mode>=0 && mode<iSystemDefaultViewIdArray.Count()) ? iSystemDefaultViewIdArray[mode] : KNullViewId; |
|
323 } |
|
324 |
|
325 TInt CVwsServer::ScreenMode() |
|
326 { |
|
327 return iWServSessionHandler->GetScreenMode(); |
|
328 } |
|
329 |
|
330 TBool CVwsServer::IsSystemDefaultView(const TVwsViewId& aViewId) |
|
331 { |
|
332 TBool ret=EFalse; |
|
333 |
|
334 const TInt numViews=iSystemDefaultViewIdArray.Count(); |
|
335 for (TInt ii=0;ii<numViews;ii++) |
|
336 { |
|
337 if (iSystemDefaultViewIdArray[ii] == aViewId) |
|
338 { |
|
339 return ETrue; |
|
340 } |
|
341 } |
|
342 |
|
343 return ret; |
|
344 } |
|
345 |
|
346 /** |
|
347 * Activates the view identified by aViewId. Immediately takes ownership of the message aClientMessage. |
|
348 */ |
|
349 void CVwsServer::ActivateViewL(const TVwsViewId& aViewId,CVwsClientMessage* aClientMessage,const RMessage2& aMessage,const TThreadId& aClientThreadId,TVwsCompleteRequest aCompleteRequest) |
|
350 { |
|
351 TVwsViewId viewId=aViewId; |
|
352 if (viewId==KNullViewId) |
|
353 { |
|
354 GetSystemDefaultView(viewId); |
|
355 } |
|
356 CleanupStack::PushL(aClientMessage); |
|
357 CVwsThreadWatcher* threadWatcher=new(ELeave) CVwsThreadWatcher(); |
|
358 CleanupStack::PushL(threadWatcher); |
|
359 CVwsEventTimer* eventTimer=CVwsEventTimer::NewLC(iClientRequestTimeOut,iServerEventTimeOut); |
|
360 RThread threadOfClientInitiatingViewSwitch; |
|
361 User::LeaveIfError(aMessage.Client(threadOfClientInitiatingViewSwitch)); |
|
362 CleanupClosePushL(threadOfClientInitiatingViewSwitch); |
|
363 CVwsServerEvent* activationEvent=new(ELeave) CVwsServerEvent_Activate(*this,CVwsServerEvent::ENormal,*iEventQueue,viewId,aClientMessage,aMessage,aClientThreadId,aCompleteRequest,threadWatcher,eventTimer,threadOfClientInitiatingViewSwitch); |
|
364 CleanupStack::Pop(4, aClientMessage); // the CVwsServerEvent_Activate object is now the owner of aClientMessage, threadWatcher, eventTimer and threadOfClientInitiatingViewSwitch |
|
365 iEventQueue->ProcessEventL(activationEvent); |
|
366 #ifdef __DO_LOGGING__ |
|
367 iNoActivationRequests++; |
|
368 LOG3(CVwsLog::ELoud,_L("Cumulative activation requests since server start - %d"),iNoActivationRequests); |
|
369 #endif |
|
370 } |
|
371 |
|
372 void CVwsServer::ActivateViewL(const TVwsViewId& aViewId,CVwsClientMessage* aClientMessage,const RMessage2& aMessage,const CVwsSession& aSession,TVwsCompleteRequest aCompleteRequest) |
|
373 { |
|
374 ActivateViewL(aViewId,aClientMessage,aMessage,aSession.ClientThreadId(),aCompleteRequest); |
|
375 } |
|
376 |
|
377 TVwsViewId CVwsServer::ActiveView() |
|
378 { |
|
379 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
380 { |
|
381 CSession2* baseSession=iSessionIter; |
|
382 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
383 |
|
384 if (thisSession->HasActiveView()) |
|
385 { |
|
386 return thisSession->ActiveView(); |
|
387 } |
|
388 } |
|
389 |
|
390 return KNullViewId; |
|
391 } |
|
392 |
|
393 void CVwsServer::SetActiveView(const TThreadId& aThreadId,const TVwsViewId& aViewId) |
|
394 { |
|
395 #ifdef _DEBUG |
|
396 TVwsViewId activeView=ActiveView(); |
|
397 |
|
398 if (activeView != KNullViewId) |
|
399 { |
|
400 LOG6(CVwsLog::EQuiet,_L("Changing active view to \"%x,%x\" [previously \"%x,%x\"]"),aViewId.iAppUid.iUid,aViewId.iViewUid.iUid,activeView.iAppUid.iUid,activeView.iViewUid.iUid); |
|
401 } |
|
402 else |
|
403 { |
|
404 LOG4(CVwsLog::EQuiet,_L("Changing active view to \"%x,%x\" [no view previously active]"),aViewId.iAppUid.iUid,aViewId.iViewUid.iUid); |
|
405 } |
|
406 #endif |
|
407 |
|
408 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
409 { |
|
410 CSession2* baseSession=iSessionIter; |
|
411 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
412 |
|
413 if (thisSession->ClientThreadId()==aThreadId) |
|
414 { |
|
415 thisSession->SetActiveView(aViewId); |
|
416 } |
|
417 else if (thisSession->HasActiveView()) |
|
418 { |
|
419 thisSession->ClearActiveView(); |
|
420 } |
|
421 } |
|
422 } |
|
423 |
|
424 void CVwsServer::ClearActiveView() |
|
425 { |
|
426 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
427 { |
|
428 CSession2* baseSession=iSessionIter; |
|
429 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
430 |
|
431 if (thisSession->HasActiveView()) |
|
432 { |
|
433 thisSession->ClearActiveView(); |
|
434 break; |
|
435 } |
|
436 } |
|
437 } |
|
438 |
|
439 void CVwsServer::SetViewAdditionObserver(MVwsViewAdditionObserver* aViewAdditionObserver) |
|
440 { |
|
441 ASSERT((iViewAdditionObserver==NULL) || (aViewAdditionObserver==NULL)); |
|
442 iViewAdditionObserver=aViewAdditionObserver; |
|
443 } |
|
444 |
|
445 void CVwsServer::HandleScreenDeviceChangedL() |
|
446 { |
|
447 LOG2(CVwsLog::ENormal,_L("Received screen device changed notification from WServ, creating event to handle it")); |
|
448 CVwsThreadWatcher* threadWatcher=new(ELeave) CVwsThreadWatcher(); |
|
449 CleanupStack::PushL(threadWatcher); |
|
450 CVwsEventTimer* eventTimer=CVwsEventTimer::NewLC(iClientRequestTimeOut,iServerEventTimeOut); |
|
451 CVwsServerEvent* screenDeviceChangedEvent=new(ELeave) CVwsServerEvent_ScreenDeviceChanged(*this,*iEventQueue,threadWatcher,eventTimer); |
|
452 CleanupStack::Pop(2); // threadWatcher, eventTimer - _ScreenDeviceChanged event is now the owner. |
|
453 iEventQueue->ProcessEventL(screenDeviceChangedEvent); |
|
454 } |
|
455 |
|
456 TInt CVwsServer::StartApp(const TUid& aAppUid,TThreadId& aThreadId) |
|
457 { |
|
458 LOG3(CVwsLog::ENormal,_L("Attempting to start app \"%x\""),aAppUid.iUid); |
|
459 TRAPD(err,iAppStarter.StartAppL(aAppUid,aThreadId)); |
|
460 return err; |
|
461 } |
|
462 |
|
463 TInt CVwsServer::CheckViewExists(const TThreadId& aThreadId,const TVwsViewId& aViewId) |
|
464 { |
|
465 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
466 { |
|
467 CSession2* baseSession=iSessionIter; |
|
468 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
469 |
|
470 if (thisSession->ClientThreadId()==aThreadId) |
|
471 { |
|
472 return thisSession->CheckViewExists(aViewId); |
|
473 } |
|
474 } |
|
475 |
|
476 return KErrNotFound; |
|
477 } |
|
478 |
|
479 CVwsSession* CVwsServer::ActiveViewSession() |
|
480 { |
|
481 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
482 { |
|
483 CSession2* baseSession=iSessionIter; |
|
484 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
485 |
|
486 if (thisSession->HasActiveView()) |
|
487 { |
|
488 return thisSession; |
|
489 } |
|
490 } |
|
491 |
|
492 return NULL; |
|
493 } |
|
494 |
|
495 CVwsSession* CVwsServer::SessionByUid(const TUid& aAppUid) |
|
496 { |
|
497 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
498 { |
|
499 CSession2* baseSession=iSessionIter; |
|
500 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
501 |
|
502 if (thisSession->AppUid()==aAppUid && !thisSession->Protected()) |
|
503 { |
|
504 return thisSession; |
|
505 } |
|
506 } |
|
507 |
|
508 return NULL; |
|
509 } |
|
510 |
|
511 CVwsSession* CVwsServer::SessionByThreadIdAndAppUid(const TThreadId& aThreadId,const TUid& aAppUid) |
|
512 { |
|
513 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
514 { |
|
515 CSession2* baseSession=iSessionIter; |
|
516 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
517 |
|
518 if (thisSession->ClientThreadId()==aThreadId && thisSession->AppUid()==aAppUid) |
|
519 { |
|
520 return thisSession; |
|
521 } |
|
522 } |
|
523 |
|
524 return NULL; |
|
525 } |
|
526 |
|
527 CVwsSession* CVwsServer::SessionByThreadId(const TThreadId& aThreadId) |
|
528 { |
|
529 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
530 { |
|
531 CSession2* baseSession=iSessionIter; |
|
532 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
533 |
|
534 if (thisSession->ClientThreadId()==aThreadId) |
|
535 { |
|
536 return thisSession; |
|
537 } |
|
538 } |
|
539 |
|
540 return NULL; |
|
541 } |
|
542 |
|
543 TBool CVwsServer::IsViewActive(const TVwsViewId& aViewId) |
|
544 { |
|
545 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
546 { |
|
547 CSession2* baseSession=iSessionIter; |
|
548 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
549 |
|
550 if (thisSession->HasActiveView()) |
|
551 { |
|
552 return thisSession->IsViewActive(aViewId); |
|
553 } |
|
554 } |
|
555 |
|
556 return EFalse; |
|
557 } |
|
558 |
|
559 void CVwsServer::RequestDeactivateActiveViewL(const RMessage2& aMessage,const CVwsSession& aSession,TVwsCompleteRequest aCompleteRequest) |
|
560 { |
|
561 LOG2(CVwsLog::ENormal,_L("Received deactivate active view request, creating event to handle it")); |
|
562 CVwsEventTimer* eventTimer=CVwsEventTimer::NewLC(iClientRequestTimeOut,iServerEventTimeOut); |
|
563 CVwsServerEvent* deactivateActiveViewEvent=new(ELeave) CVwsServerEvent_DeactivateActiveView(*this,*iEventQueue,aMessage,aSession.ClientThreadId(),aCompleteRequest,eventTimer); |
|
564 CleanupStack::Pop(); // eventTimer - _DeactivateActiveView event is now the owner. |
|
565 iEventQueue->ProcessEventL(deactivateActiveViewEvent); |
|
566 } |
|
567 |
|
568 void CVwsServer::RequestAppStartL(const RMessage2& aMessage,const TUid& aAppToStart) |
|
569 { |
|
570 LOG2(CVwsLog::ENormal,_L("Received start app request, creating event to handle it")); |
|
571 CVwsThreadWatcher* threadWatcher=new(ELeave) CVwsThreadWatcher(); |
|
572 CleanupStack::PushL(threadWatcher); |
|
573 CVwsServerEvent* appStartEvent=new(ELeave) CVwsServerEvent_AppStart(*this,*iEventQueue,aMessage,aAppToStart,threadWatcher); |
|
574 CleanupStack::Pop(); // threadWatcher |
|
575 iEventQueue->ProcessEventL(appStartEvent); |
|
576 } |
|
577 |
|
578 void CVwsServer::HandleDeactivation(const TVwsViewId& aDeactivatedViewId, const TVwsViewId& aActivatedViewId) |
|
579 { |
|
580 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
581 { |
|
582 CSession2* baseSession=iSessionIter; |
|
583 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
584 TRAP_IGNORE(thisSession->HandleDeactivationL(aDeactivatedViewId,aActivatedViewId)); |
|
585 } |
|
586 } |
|
587 |
|
588 void CVwsServer::HandleActivation(const TVwsViewId& aActivatedViewId, const TVwsViewId& aViewIdToBeDeactivated) |
|
589 { |
|
590 for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) |
|
591 { |
|
592 CSession2* baseSession=iSessionIter; |
|
593 CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); |
|
594 TRAP_IGNORE(thisSession->HandleActivationL(aActivatedViewId,aViewIdToBeDeactivated)); |
|
595 } |
|
596 } |
|
597 |
|
598 void CVwsServer::MakeInterceptingWindowVisible() |
|
599 { |
|
600 if (iEnableServerBlankScreen) |
|
601 { |
|
602 iWServSessionHandler->DisplayWindow(); |
|
603 } |
|
604 } |
|
605 |
|
606 void CVwsServer::MakeInterceptingWindowInvisible() |
|
607 { |
|
608 if (iEnableServerBlankScreen) |
|
609 { |
|
610 iWServSessionHandler->HideWindow(); |
|
611 } |
|
612 } |
|
613 |
|
614 void CVwsServer::MakeInterceptingWindowVisibleAndUpdateScreen() |
|
615 { |
|
616 if (iEnableServerBlankScreen) |
|
617 { |
|
618 iWServSessionHandler->UpdateScreenAndDisplayWindow(); |
|
619 } |
|
620 } |
|
621 |
|
622 void CVwsServer::HandleSessionViewAddition(const TVwsViewId& aViewId, const TThreadId& aNewViewClientThreadId) |
|
623 { |
|
624 if (iViewAdditionObserver) |
|
625 { |
|
626 iViewAdditionObserver->HandleViewAdded(aViewId, aNewViewClientThreadId); |
|
627 } |
|
628 } |
|
629 |
|
630 void CVwsServer::HandleSessionRemoval(const TThreadId& aThreadId) |
|
631 { |
|
632 iEventQueue->HandleSessionRemoval(aThreadId); |
|
633 } |
|
634 |
|
635 /* Check that the thread that has keyboard focus also has the active view. |
|
636 * Activate a new view if not. |
|
637 */ |
|
638 void CVwsServer::CrossCheckForegroundTask() |
|
639 { |
|
640 //Get the focused window group; |
|
641 RWsSession& wsSession=iWServSessionHandler->WsSession(); |
|
642 TInt fgAppWgId=wsSession.GetFocusWindowGroup(); |
|
643 if (fgAppWgId) |
|
644 { |
|
645 CVwsSession* activeSession=ActiveViewSession(); |
|
646 TThreadId fgAppThreadId; |
|
647 //Get the thread that owns this Window group. |
|
648 if (wsSession.GetWindowGroupClientThreadId(fgAppWgId,fgAppThreadId)==KErrNotFound) |
|
649 { |
|
650 fgAppThreadId=TThreadId(0); |
|
651 } |
|
652 if (!(activeSession && activeSession->ClientThreadId()==fgAppThreadId) && SessionByThreadId(fgAppThreadId)) |
|
653 { |
|
654 LOG2(CVwsLog::ELoud,_L("Foreground app cross-check failed - notifying foreground app that it needs to activate a view")); |
|
655 if(iCrossCheckUid!=KNullUid) |
|
656 { |
|
657 // We can't do anything about the leave here, so trap and ignore it |
|
658 TRAP_IGNORE(SendCrossCheckToLauncherL(wsSession, fgAppWgId, ActiveView())); |
|
659 } |
|
660 else |
|
661 { |
|
662 TWsEvent event; |
|
663 event.SetType(EEventUser); |
|
664 *(TApaSystemEvent*)(event.EventData())=EApaSystemEventBroughtToForeground; |
|
665 event.SetTimeNow(); |
|
666 wsSession.SendEventToWindowGroup(fgAppWgId,event); |
|
667 } |
|
668 } |
|
669 } |
|
670 } |
|
671 |
|
672 void CVwsServer::HandleLastServerEventOnQueue() |
|
673 { |
|
674 MakeInterceptingWindowInvisible(); |
|
675 if (iForegroundChangeWhileEventsOutstanding) |
|
676 { |
|
677 iForegroundChangeWhileEventsOutstanding=EFalse; |
|
678 CrossCheckForegroundTask(); |
|
679 } |
|
680 } |
|
681 |
|
682 void CVwsServer::HandleForegroundTaskChange() |
|
683 { |
|
684 if (iEventQueue->Count()>0) |
|
685 { |
|
686 iForegroundChangeWhileEventsOutstanding=ETrue; |
|
687 } |
|
688 else |
|
689 { |
|
690 CrossCheckForegroundTask(); |
|
691 } |
|
692 } |
|
693 |
|
694 void CVwsServer::KickStartEventQ() |
|
695 { |
|
696 iEventQueue->KickStart(); |
|
697 } |
|
698 |
|
699 CPolicyServer::TCustomResult CVwsServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/) |
|
700 //aAction is not set because default value to it is already set(CPolicyServer::EFailClient) |
|
701 //aMissing is not set because it is not needed as we aren't overriding CheckFailedL |
|
702 { |
|
703 CPolicyServer::TCustomResult returnValue = CPolicyServer::EFail; |
|
704 |
|
705 // Check that the client either has SID of Eiksrvs or WriteDeviceData capability |
|
706 if(aMsg.SecureId()==KEiksrvsSid || aMsg.HasCapability(ECapabilityWriteDeviceData)) |
|
707 { |
|
708 returnValue = CPolicyServer::EPass; |
|
709 } |
|
710 |
|
711 return(returnValue); |
|
712 } |
|
713 void CVwsServer::GetPriorityForActiveObjectL(TInt& aPriority) |
|
714 { |
|
715 aPriority=iPrioritySet; |
|
716 } |
|
717 |
|
718 struct TCrossCheckParam |
|
719 { |
|
720 TVwsViewId iActiveView; |
|
721 TInt iFgAppWgId; |
|
722 }; |
|
723 |
|
724 void CVwsServer::SetCrossCheckUid(const RMessage2& aMessage) |
|
725 { |
|
726 iCrossCheckUid.iUid=aMessage.Int0(); |
|
727 } |
|
728 |
|
729 TUid CVwsServer::CrossCheckUid() const |
|
730 { |
|
731 return iCrossCheckUid; |
|
732 } |
|
733 |
|
734 void CVwsServer::SendCrossCheckToLauncherL(RWsSession& aWsSession, TInt aFgAppWgId, const TVwsViewId& aActiveView) |
|
735 { |
|
736 TInt launcherWgId = 0; |
|
737 const TInt KPriority = -1; |
|
738 TInt wgCount = aWsSession.NumWindowGroups(KPriority); |
|
739 if (wgCount) |
|
740 { |
|
741 CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(aWsSession); |
|
742 CArrayFixFlat<TInt>* wgIdArray = new(ELeave) CArrayFixFlat<TInt>(wgCount); |
|
743 CleanupStack::PushL(wgIdArray); |
|
744 User::LeaveIfError(aWsSession.WindowGroupList(KPriority, wgIdArray)); |
|
745 const TInt KCount = wgIdArray->Count(); |
|
746 for (TInt i = 0; i < KCount; ++i) |
|
747 { |
|
748 const TInt wgId = (*wgIdArray)[i]; |
|
749 wgName->ConstructFromWgIdL(wgId); |
|
750 if (wgName->AppUid() == iCrossCheckUid) |
|
751 { |
|
752 launcherWgId = wgId; |
|
753 break; |
|
754 } |
|
755 } |
|
756 CleanupStack::PopAndDestroy(2, wgName); // wgIdArray, wgName |
|
757 } |
|
758 |
|
759 if (launcherWgId) |
|
760 { |
|
761 TWsEvent wsEvent; |
|
762 wsEvent.SetType(EEventUser + 256); // Change this later |
|
763 wsEvent.SetTimeNow(); |
|
764 TCrossCheckParam* param = reinterpret_cast<TCrossCheckParam*>(wsEvent.EventData()); |
|
765 param->iActiveView = aActiveView; |
|
766 param->iFgAppWgId = aFgAppWgId; |
|
767 aWsSession.SendEventToWindowGroup(launcherWgId, wsEvent); |
|
768 } |
|
769 }; |
|
770 |
|
771 void CVwsServer::SetWindowBackgroundColor(const RMessage2& aMessage) |
|
772 { |
|
773 TRgb color; |
|
774 color.SetInternal(aMessage.Int0()); |
|
775 iWServSessionHandler->SetWindowBackgroundColor(color); |
|
776 } |
|
777 |
|
778 // Gets the active viewid of the foreground application |
|
779 void CVwsServer::GetCurrentActiveViewId(TVwsViewId& aActiveViewId) |
|
780 { |
|
781 aActiveViewId = ActiveView(); |
|
782 } |
|
783 |
|
784 // Tells if the application whose view is getting activated is in foreground or background |
|
785 TBool CVwsServer::IsAppInForeground() |
|
786 { |
|
787 TBool isAppInForeground = EFalse; |
|
788 RWsSession& wsSession = iWServSessionHandler->WsSession(); |
|
789 TInt fgAppWgId = wsSession.GetFocusWindowGroup(); |
|
790 if (fgAppWgId) |
|
791 { |
|
792 CVwsSession* activeSession = ActiveViewSession(); |
|
793 TThreadId fgAppThreadId; |
|
794 // Get the thread that owns this Window group. |
|
795 // GetWindowGroupClientThreadId() either returns KErrNone or KErrNotFound error code |
|
796 if (wsSession.GetWindowGroupClientThreadId(fgAppWgId,fgAppThreadId) == KErrNotFound) |
|
797 { |
|
798 fgAppThreadId = TThreadId(0); |
|
799 } |
|
800 |
|
801 if (!(activeSession && (activeSession->ClientThreadId() == fgAppThreadId)) && SessionByThreadId(fgAppThreadId)) |
|
802 { |
|
803 isAppInForeground = ETrue; |
|
804 } |
|
805 } |
|
806 return isAppInForeground; |
|
807 } |
|
808 |
|
809 TBool CVwsServer::InitializationFinished() const |
|
810 { |
|
811 return iInitializationFinished; |
|
812 } |
|
813 |
|
814 TInt CVwsServer::IsPriorityBoostBeforePanicEnabled()const |
|
815 { |
|
816 return iEnableBoostAppPriorityBeforePanic; |
|
817 } |
|
818 |
|
819 void CVwsServer::HandleInitializationFinished() |
|
820 { |
|
821 iInitializationFinished = ETrue; |
|
822 } |
|
823 |
|
824 void CVwsServer::BoostPriority(CVwsSession* aClient) |
|
825 { |
|
826 if (!aClient) |
|
827 { |
|
828 return; |
|
829 } |
|
830 if (!IsPriorityBoostBeforePanicEnabled()) |
|
831 { |
|
832 return; |
|
833 } |
|
834 |
|
835 RThread starved; |
|
836 if (starved.Open(aClient->ClientThreadId()) != KErrNone) |
|
837 { |
|
838 return; |
|
839 } |
|
840 |
|
841 if (starved.ProcessPriority() < EPriorityForeground) |
|
842 { |
|
843 RProcess owningProcess; |
|
844 TInt err = starved.Process(owningProcess); |
|
845 if (err != KErrNone) |
|
846 { |
|
847 starved.Close(); |
|
848 return; |
|
849 } |
|
850 owningProcess.SetPriority(EPriorityForeground); |
|
851 owningProcess.Close(); |
|
852 } |
|
853 |
|
854 starved.Close(); |
|
855 } |
|
856 |