1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of "Eclipse Public License v1.0" |
4 // under the terms of "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
23 #ifdef TEST_SURFACE_UPDATE |
23 #ifdef TEST_SURFACE_UPDATE |
24 #include "surfaceupdatetest.h" |
24 #include "surfaceupdatetest.h" |
25 #endif |
25 #endif |
26 |
26 |
27 |
27 |
28 |
|
29 const TUint KDefaultHeapSize=0x10000; |
28 const TUint KDefaultHeapSize=0x10000; |
30 |
29 |
|
30 void *gProvider = NULL; |
|
31 RFastLock gProviderFastLock; |
31 |
32 |
32 /** |
33 /** |
33 The server maintains session with the clients. |
34 The server maintains session with the clients. |
34 It starts during the initialization of the Content update receiver thread. |
35 It starts during the initialization of the Content update receiver thread. |
35 */ |
36 */ |
349 */ |
350 */ |
350 CUpdateReceiverNotificationBatch* CSurfaceUpdateSession::UpdateReceiverNotificationBatchL() |
351 CUpdateReceiverNotificationBatch* CSurfaceUpdateSession::UpdateReceiverNotificationBatchL() |
351 { |
352 { |
352 TInt numElement = iUpdateReceiverNotificationBatches.Count(); |
353 TInt numElement = iUpdateReceiverNotificationBatches.Count(); |
353 CUpdateReceiverNotificationBatch* notifier = NULL; |
354 CUpdateReceiverNotificationBatch* notifier = NULL; |
|
355 CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server(); |
354 for(TInt index = 0; index < numElement; index++) |
356 for(TInt index = 0; index < numElement; index++) |
355 { |
357 { |
356 notifier = iUpdateReceiverNotificationBatches[index]; |
358 notifier = iUpdateReceiverNotificationBatches[index]; |
357 if(notifier->iType == EUpdateSrvReusable) |
359 if(notifier->iType == EUpdateSrvReusable) |
358 { |
360 { |
359 __ASSERT_ALWAYS(notifier->iMsg.IsNull(), CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity)); |
361 __ASSERT_ALWAYS(notifier->iMsg.IsNull(), CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity)); |
|
362 notifier->SetNumUpdateReceivers(server->NumUpdateReceivers()); |
360 if(numElement > index + 1) |
363 if(numElement > index + 1) |
361 { |
364 { |
362 //to improve a search, append the element to the end of the array |
365 //to improve a search, append the element to the end of the array |
363 iUpdateReceiverNotificationBatches.Remove(index); |
366 iUpdateReceiverNotificationBatches.Remove(index); |
364 iUpdateReceiverNotificationBatches.AppendL(notifier); |
367 iUpdateReceiverNotificationBatches.AppendL(notifier); |
365 } |
368 } |
366 return notifier; |
369 return notifier; |
367 } |
370 } |
368 } |
371 } |
369 |
372 |
370 CSurfaceUpdateServer* server = (CSurfaceUpdateServer*) Server(); |
|
371 notifier = new (ELeave) CUpdateReceiverNotificationBatch(this, server->NumUpdateReceivers()); |
373 notifier = new (ELeave) CUpdateReceiverNotificationBatch(this, server->NumUpdateReceivers()); |
372 CleanupStack::PushL(notifier); |
374 CleanupStack::PushL(notifier); |
373 iUpdateReceiverNotificationBatches.AppendL(notifier); |
375 iUpdateReceiverNotificationBatches.AppendL(notifier); |
374 CleanupStack::Pop(); |
376 CleanupStack::Pop(); |
375 |
377 |
881 (static_cast<CSurfaceUpdateServer*> (server))-> iNumberPendingNotification++; |
883 (static_cast<CSurfaceUpdateServer*> (server))-> iNumberPendingNotification++; |
882 } |
884 } |
883 } |
885 } |
884 #endif |
886 #endif |
885 |
887 |
|
888 |
|
889 /** |
|
890 Set number of UpdateReceivers - called when update receivers are added/removed. |
|
891 |
|
892 @param aNumUpdateReceivers - new number of update receivers for the batch. |
|
893 */ |
|
894 void CUpdateReceiverNotificationBatch::SetNumUpdateReceivers(TInt aNumUpdateReceivers) |
|
895 { |
|
896 __ASSERT_DEBUG(aNumUpdateReceivers >= 0 && aNumUpdateReceivers < 1000 /* arbitrary "large" limit */, |
|
897 CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity)); |
|
898 __ASSERT_DEBUG(iType == EUpdateSrvReusable, |
|
899 CSurfaceUpdateServer::PanicServer(EUpdateServPanicDataIntegrity)); |
|
900 iNumUpdateReceivers = aNumUpdateReceivers; |
|
901 } |
886 /** |
902 /** |
887 |
903 |
888 The class will be used by composition receiver |
904 The class will be used by composition receiver |
889 */ |
905 */ |
890 CSurfaceUpdateServerProvider* CSurfaceUpdateServerProvider::NewL(CActive::TPriority aPriority, CSurfaceUpdateServer* aServer) |
906 CSurfaceUpdateServerProvider* CSurfaceUpdateServerProvider::NewL(CActive::TPriority aPriority, CSurfaceUpdateServer* aServer) |
953 #ifdef TEST_SURFACE_UPDATE |
969 #ifdef TEST_SURFACE_UPDATE |
954 RThread thread; |
970 RThread thread; |
955 |
971 |
956 if(thread.Open(iThreadId) == KErrNone) |
972 if(thread.Open(iThreadId) == KErrNone) |
957 { |
973 { |
|
974 TInt err = gProviderFastLock.CreateLocal(); |
|
975 __ASSERT_ALWAYS(err == KErrNone || err == KErrAlreadyExists, CSurfaceUpdateServer::PanicServer(EUpdateServPanicGlobalFastLock)); |
|
976 |
|
977 gProviderFastLock.Wait(); |
|
978 gProvider = NULL; |
958 if (iServer) |
979 if (iServer) |
959 { |
980 { |
960 while((static_cast<CSurfaceUpdateServer*> (iServer))-> iNumberPendingNotification) |
981 while((static_cast<CSurfaceUpdateServer*> (iServer))-> iNumberPendingNotification) |
961 User::After(TTimeIntervalMicroSeconds32(1000)); |
982 User::After(TTimeIntervalMicroSeconds32(1000)); |
962 } |
983 } |
1012 which will be set when the server is started. The variable will be used to registry |
1033 which will be set when the server is started. The variable will be used to registry |
1013 composition receiver instances. The caller doesn't acquire the ownership of this instance, |
1034 composition receiver instances. The caller doesn't acquire the ownership of this instance, |
1014 thus mustn't delete it. The pointer will be valid until server is operating, |
1035 thus mustn't delete it. The pointer will be valid until server is operating, |
1015 i.e. system is up. |
1036 i.e. system is up. |
1016 |
1037 |
1017 @panic KErrAccessDenied If is called from process other than WSERV. |
|
1018 @return KErrNone if an operation is successful, any other system error codes otherwise |
1038 @return KErrNone if an operation is successful, any other system error codes otherwise |
1019 */ |
1039 */ |
1020 EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider) |
1040 EXPORT_C TInt StartSurfaceUpdateServer(MSurfaceUpdateServerProvider*& aSurfaceUpdateServerProvider) |
1021 { |
1041 { |
1022 #ifndef TEST_SURFACE_UPDATE |
1042 #ifndef TEST_SURFACE_UPDATE |
1023 RProcess process; |
|
1024 TUidType uidType = process.Type(); |
|
1025 const TInt32 KWservUid = 268450592; |
|
1026 const TUid& uid1 = uidType[2]; |
|
1027 |
|
1028 if(uid1.iUid != KWservUid) //only wserv process can start the server |
|
1029 {// some malicious client tries to launch the server |
|
1030 process.Panic(_L("Access denied"), KErrAccessDenied); |
|
1031 return KErrAccessDenied; |
|
1032 } |
|
1033 TPtrC serverName(KSurfaceUpdateServerName); |
1043 TPtrC serverName(KSurfaceUpdateServerName); |
1034 #else |
1044 #else |
1035 TPtrC serverName(KTestSurfaceUpdateServerName); |
1045 TPtrC serverName(KTestSurfaceUpdateServerName); |
1036 #endif |
1046 #endif |
1037 TAny *provider = Dll::Tls(); |
1047 //locking |
|
1048 TInt err = gProviderFastLock.CreateLocal(); |
|
1049 |
|
1050 if (err != KErrNone && err != KErrAlreadyExists) |
|
1051 { |
|
1052 return err; |
|
1053 } |
|
1054 |
|
1055 gProviderFastLock.Wait(); |
|
1056 |
|
1057 TAny *provider = gProvider; |
1038 if(provider) |
1058 if(provider) |
1039 { |
1059 { |
1040 aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider); |
1060 aSurfaceUpdateServerProvider = static_cast <MSurfaceUpdateServerProvider*> (provider); |
|
1061 gProviderFastLock.Signal(); |
1041 return KErrNone; |
1062 return KErrNone; |
1042 } |
1063 } |
1043 TFullName name; |
1064 TFullName name; |
1044 RThread serverThread; |
1065 RThread serverThread; |
1045 TInt res = KErrAlreadyExists; |
1066 TInt res = KErrAlreadyExists; |
1052 TBuf<32> buf; |
1073 TBuf<32> buf; |
1053 tm.UniversalTime(); |
1074 tm.UniversalTime(); |
1054 TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C"))); |
1075 TRAP(res, tm.FormatL(buf, _L("_%H%T%S%C"))); |
1055 if(res != KErrNone) |
1076 if(res != KErrNone) |
1056 { |
1077 { |
|
1078 gProviderFastLock.Signal(); |
1057 return res; |
1079 return res; |
1058 } |
1080 } |
1059 TBuf<128> threadName(serverName); |
1081 TBuf<128> threadName(serverName); |
1060 threadName.Append(buf); //guarantee uniqueness of the thread name |
1082 threadName.Append(buf); //guarantee uniqueness of the thread name |
1061 // Create the thread for the server. |
1083 // Create the thread for the server. |
1075 serverThread.SetPriority(priority); // The same as the priority of the creating thread |
1097 serverThread.SetPriority(priority); // The same as the priority of the creating thread |
1076 serverThread.Rendezvous(rendezvousStatus); |
1098 serverThread.Rendezvous(rendezvousStatus); |
1077 serverThread.Resume(); |
1099 serverThread.Resume(); |
1078 User::WaitForRequest(rendezvousStatus); |
1100 User::WaitForRequest(rendezvousStatus); |
1079 res = rendezvousStatus.Int(); |
1101 res = rendezvousStatus.Int(); |
1080 Dll::SetTls(aSurfaceUpdateServerProvider); |
1102 gProvider = aSurfaceUpdateServerProvider; |
1081 } |
1103 } |
1082 // The thread has not been created - clearly there's been a problem. |
1104 // The thread has not been created - clearly there's been a problem. |
1083 else |
1105 else |
1084 { |
1106 { |
1085 serverThread.Close(); |
1107 serverThread.Close(); |
1086 } |
1108 } |
1087 } |
1109 } |
|
1110 gProviderFastLock.Signal(); |
1088 return res; |
1111 return res; |
1089 } |
1112 } |