42 #include "xqserviceipcconst.h" |
42 #include "xqserviceipcconst.h" |
43 |
43 |
44 #include "xqservicemetadata/xqservicemetadata_p.h" |
44 #include "xqservicemetadata/xqservicemetadata_p.h" |
45 #include <xqservicemetadata/xqaiwinterfacedescriptor.h> |
45 #include <xqservicemetadata/xqaiwinterfacedescriptor.h> |
46 #include "xqconversions.h" |
46 #include "xqconversions.h" |
47 |
47 #include "processinfo.h" |
48 |
48 |
49 #define TIMER_DELAY 3000000 // 3000000 microseconds == 3s |
|
50 |
|
51 class CProcessInfo : public CActive |
|
52 { |
|
53 public: |
|
54 static void AddProcessL(const TUid& appUid, RProcess& appProcess); |
|
55 static bool EnsureProcessCanStartL(const TUid& appUid); |
|
56 |
|
57 protected: |
|
58 CProcessInfo(const TUid& appUid); |
|
59 ~CProcessInfo(); |
|
60 void ConstructL(RProcess& appProcess); |
|
61 void DoCancel(); |
|
62 void RunL(); |
|
63 |
|
64 protected: |
|
65 class ProcessInfoMap |
|
66 { |
|
67 public: |
|
68 ~ProcessInfoMap() |
|
69 { |
|
70 foreach (CProcessInfo* info, map.values()) |
|
71 delete info; |
|
72 } |
|
73 QHash<TInt32, CProcessInfo*> map; |
|
74 }; |
|
75 |
|
76 static ProcessInfoMap iProcessInfoMap; |
|
77 const TUid iAppUid; |
|
78 }; |
|
79 |
|
80 |
|
81 |
|
82 CProcessInfo::ProcessInfoMap CProcessInfo::iProcessInfoMap; |
|
83 |
|
84 CProcessInfo::CProcessInfo(const TUid& appUid): |
|
85 CActive(CActive::EPriorityStandard), |
|
86 iAppUid(appUid) |
|
87 { |
|
88 XQSERVICE_DEBUG_PRINT("CProcessInfo::CProcessInfo"); |
|
89 |
|
90 CActiveScheduler::Add(this); |
|
91 } |
|
92 |
|
93 CProcessInfo::~CProcessInfo() |
|
94 { |
|
95 XQSERVICE_DEBUG_PRINT("CProcessInfo::~CProcessInfo"); |
|
96 |
|
97 // Cancel asynch request, normally it should be done in DoCancel() |
|
98 // but we dont wont to cancel request when we cancel active object |
|
99 User::CancelMiscNotifier(iStatus); |
|
100 |
|
101 Cancel(); |
|
102 } |
|
103 |
|
104 void CProcessInfo::AddProcessL(const TUid& appUid, RProcess& appProcess) |
|
105 { |
|
106 XQSERVICE_DEBUG_PRINT("CProcessInfo::AddProcessL"); |
|
107 |
|
108 CProcessInfo* self = new(ELeave) CProcessInfo(appUid); |
|
109 CleanupStack::PushL(self); |
|
110 self->ConstructL(appProcess); |
|
111 CleanupStack::Pop(self); |
|
112 } |
|
113 |
|
114 bool CProcessInfo::EnsureProcessCanStartL(const TUid& appUid) |
|
115 { |
|
116 XQSERVICE_DEBUG_PRINT("CProcessInfo::EnsureProcessCanStartL"); |
|
117 |
|
118 bool ret = true; |
|
119 |
|
120 CProcessInfo* previousProcess = iProcessInfoMap.map[appUid.iUid]; |
|
121 if (previousProcess) { |
|
122 // Timer is for ensure that wait will end. |
|
123 // Maybe there is possibility that destroing process notification could be lost. |
|
124 RTimer securityTimer; |
|
125 securityTimer.CreateLocal(); |
|
126 CleanupClosePushL(securityTimer); |
|
127 |
|
128 TRequestStatus timerStatus; |
|
129 securityTimer.After(timerStatus, TIMER_DELAY); |
|
130 User::WaitForRequest(previousProcess->iStatus, timerStatus); |
|
131 |
|
132 if (previousProcess->iStatus == KRequestPending) |
|
133 ret = false; |
|
134 |
|
135 CleanupStack::PopAndDestroy(); |
|
136 delete previousProcess; |
|
137 iProcessInfoMap.map.remove(appUid.iUid); |
|
138 } |
|
139 return ret; |
|
140 } |
|
141 |
|
142 void CProcessInfo::RunL() |
|
143 { |
|
144 XQSERVICE_DEBUG_PRINT("CProcessInfo::RunL"); |
|
145 |
|
146 iProcessInfoMap.map.remove(iAppUid.iUid); |
|
147 delete this; |
|
148 } |
|
149 |
|
150 void CProcessInfo::ConstructL(RProcess& appProcess) |
|
151 { |
|
152 XQSERVICE_DEBUG_PRINT("CProcessInfo::ConstructL"); |
|
153 |
|
154 SetActive(); |
|
155 |
|
156 EnsureProcessCanStartL(iAppUid); |
|
157 iProcessInfoMap.map.insert(iAppUid.iUid, this); |
|
158 appProcess.NotifyDestruction(iStatus); |
|
159 } |
|
160 |
|
161 void CProcessInfo::DoCancel() |
|
162 { |
|
163 XQSERVICE_DEBUG_PRINT("CProcessInfo::DoCancel"); |
|
164 |
|
165 // Cancel asynch request, normally it should be done in DoCancel() |
|
166 // but we dont wont to cancel request when we cancel active object. |
|
167 // Cancel asynch request is in ~CProcessInfo(). |
|
168 } |
|
169 |
49 |
170 /*! |
50 /*! |
171 \class XQServiceManagerPrivate |
51 \class XQServiceManagerPrivate |
172 \brief Private implementation of the XQServiceManager. |
52 \brief Private implementation of the XQServiceManager. |
173 */ |
53 */ |
498 } |
380 } |
499 else { |
381 else { |
500 if(!CProcessInfo::EnsureProcessCanStartL(uid)) |
382 if(!CProcessInfo::EnsureProcessCanStartL(uid)) |
501 User::Leave(KErrAlreadyExists); |
383 User::Leave(KErrAlreadyExists); |
502 } |
384 } |
|
385 CleanupStack::PopAndDestroy(&client); |
|
386 |
503 TRequestStatus requestStatusForRendezvous; |
387 TRequestStatus requestStatusForRendezvous; |
504 |
388 |
505 // start application with command line parameters |
389 // start application with command line parameters |
506 //User::LeaveIfError( iApaSession.StartApp( *cmdLine, threadId, &requestStatusForRendezvous) ); |
390 //User::LeaveIfError( iApaSession.StartApp( *cmdLine, threadId, &requestStatusForRendezvous) ); |
507 QString startupArgs = QString::fromLatin1(XQServiceUtils::StartupArgService); |
391 QString startupArgs = QString::fromLatin1(XQServiceUtils::StartupArgService); |