|
1 // Copyright (c) 2004-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 "csendasserver.h" |
|
17 |
|
18 #include <ecom/ecom.h> |
|
19 #include <barsc.h> |
|
20 #include <barsread.h> |
|
21 |
|
22 #include "csendassession.h" |
|
23 #include "csendasservertimer.h" |
|
24 #include "sendasserverdefs.h" |
|
25 #include "sendasservername.h" |
|
26 #include "csendasactivecontainer.h" |
|
27 #include "csendasmtmmanager.h" |
|
28 |
|
29 // time the server will stay alive after the last session closes. |
|
30 const TInt KSendAsServerCloseTime = 2000000; // 2 seconds |
|
31 |
|
32 // time the server will stay alive between starting and the first connect |
|
33 // operation arriving. |
|
34 const TInt KSendAsServerInitCloseTime = 10000000; // 10 seconds |
|
35 |
|
36 // location of the server resource file and resource struct version number |
|
37 _LIT(KSendAsServerResourceFile,"Z:\\resource\\messaging\\sendasserver.rsc"); |
|
38 const TInt KResVersion = 0x00000001; |
|
39 |
|
40 /** Factory function to create a new instance of the SendAs server. |
|
41 |
|
42 @return |
|
43 A new CSendAsServer object. This object is left on the cleanup stack. |
|
44 */ |
|
45 CSendAsServer* CSendAsServer::NewLC() |
|
46 { |
|
47 CSendAsServer* self = new (ELeave) CSendAsServer; |
|
48 CleanupStack::PushL(self); |
|
49 self->ConstructL(); |
|
50 return self; |
|
51 } |
|
52 |
|
53 /** Second-stage constructor. |
|
54 |
|
55 Here the server allocates the 'object container index' object that is used to |
|
56 keep track of the sessions. |
|
57 */ |
|
58 void CSendAsServer::ConstructL() |
|
59 { |
|
60 iMsvSession = CMsvSession::OpenSyncL(*this); |
|
61 iContainerIndex = CObjectConIx::NewL(); |
|
62 |
|
63 iMtmManager = CSendAsMtmManager::NewL(*this); |
|
64 |
|
65 // read UIDs for edit tools and confirmation notifier from file |
|
66 ReadResourceFileL(); |
|
67 |
|
68 // configure the close timer to shut us down if there are no sessions |
|
69 // connected in the first 10 seconds. |
|
70 iCloseTimer = CSendAsServerTimer::NewL(); |
|
71 iCloseTimer->After(KSendAsServerInitCloseTime); |
|
72 |
|
73 iActiveContainer = CSendAsActiveContainer::NewL(*this); |
|
74 |
|
75 StartL(KSendAsServerName); |
|
76 } |
|
77 |
|
78 CSendAsServer::CSendAsServer() |
|
79 : CServer2(CActive::EPriorityStandard) |
|
80 { |
|
81 } |
|
82 |
|
83 CSendAsServer::~CSendAsServer() |
|
84 { |
|
85 delete iCloseTimer; |
|
86 delete iContainerIndex; |
|
87 delete iActiveContainer; |
|
88 delete iMtmManager; |
|
89 delete iMsvSession; |
|
90 |
|
91 REComSession::FinalClose(); |
|
92 } |
|
93 |
|
94 /** Create a new session. |
|
95 |
|
96 Called inside the NewSessionL callback. This creates a new session |
|
97 using the factory function. The new session will call back into the server to |
|
98 request an object container from the index during the operation of this factory function. |
|
99 */ |
|
100 CSession2* CSendAsServer::DoNewSessionL(const TVersion& aVersion, const RMessage2& /*aMsg*/) |
|
101 { |
|
102 // stop the delayed startup shutdown mechanism |
|
103 iCloseTimer->Cancel(); |
|
104 |
|
105 CSendAsSession* session = CSendAsSession::NewL(aVersion, *this); |
|
106 return session; |
|
107 } |
|
108 |
|
109 /** Create a new session. |
|
110 |
|
111 The callback called by the server framework when a client calls Connect on an RSession-derived |
|
112 object. |
|
113 In the SendAs Server, a server-side CSendAsSession represents an RSendAs client-side object. |
|
114 */ |
|
115 CSession2* CSendAsServer::NewSessionL(const TVersion& aVersion, const RMessage2& aMsg) const |
|
116 { |
|
117 return ((CSendAsServer*)this)->DoNewSessionL(aVersion, aMsg); |
|
118 } |
|
119 |
|
120 /** Generate a new object container for the session. |
|
121 |
|
122 (Callback from session creation factory function). |
|
123 Server remembers how many sessions are open. |
|
124 */ |
|
125 CObjectCon* CSendAsServer::NewContainerL() |
|
126 { |
|
127 CObjectCon* con = iContainerIndex->CreateL(); |
|
128 ++iOpenSessions; |
|
129 return con; |
|
130 } |
|
131 |
|
132 /** Indication of session closing down. |
|
133 |
|
134 Called from the session destructor to allow the server to dereference the |
|
135 object container for that session. |
|
136 */ |
|
137 void CSendAsServer::SessionClosed(CObjectCon* aSessionContainer) |
|
138 { |
|
139 if( aSessionContainer != NULL) |
|
140 { |
|
141 iContainerIndex->Remove(aSessionContainer); |
|
142 --iOpenSessions; |
|
143 if( iOpenSessions == 0 ) |
|
144 { |
|
145 if ( iActiveContainer->IsEmpty() ) |
|
146 { |
|
147 iCloseTimer->After(KSendAsServerCloseTime); |
|
148 } |
|
149 else |
|
150 { |
|
151 // ensure no orphaned entries in background task container |
|
152 iActiveContainer->PurgeInactive(); |
|
153 } |
|
154 } |
|
155 } |
|
156 } |
|
157 |
|
158 CSendAsActiveContainer& CSendAsServer::ActiveContainer() |
|
159 { |
|
160 return *iActiveContainer; |
|
161 } |
|
162 |
|
163 void CSendAsServer::ContainerEmpty() |
|
164 { |
|
165 // if no open sessions, start server shutdown timer |
|
166 if( iOpenSessions == 0 ) |
|
167 { |
|
168 iCloseTimer->After(KSendAsServerCloseTime); |
|
169 } |
|
170 } |
|
171 |
|
172 void CSendAsServer::ReadResourceFileL() |
|
173 { |
|
174 RFs fs; |
|
175 User::LeaveIfError(fs.Connect()); |
|
176 CleanupClosePushL(fs); |
|
177 |
|
178 RResourceFile file; |
|
179 file.OpenL(fs, KSendAsServerResourceFile); |
|
180 |
|
181 CleanupClosePushL(file); |
|
182 |
|
183 // Read the resource |
|
184 HBufC8* resBuf = file.AllocReadLC(1); |
|
185 |
|
186 // interpret the resource buffer |
|
187 TResourceReader reader; |
|
188 reader.SetBuffer(resBuf); |
|
189 |
|
190 // Read Edit Tools plugin UID and SendAs Confirm Notifier UID |
|
191 TInt resVersion = reader.ReadInt32(); |
|
192 iEditUtilsPluginUid = TUid::Uid(reader.ReadInt32()); |
|
193 iNotifierUid = TUid::Uid(reader.ReadInt32()); |
|
194 |
|
195 if (resVersion != KResVersion || iEditUtilsPluginUid == KNullUid || iNotifierUid == KNullUid) |
|
196 { |
|
197 User::Leave(KErrCorrupt); |
|
198 } |
|
199 |
|
200 CleanupStack::PopAndDestroy(3, &fs); // resBuf, file, fs |
|
201 } |
|
202 |
|
203 const TUid& CSendAsServer::NotifierUid() const |
|
204 { |
|
205 return iNotifierUid; |
|
206 } |
|
207 |
|
208 const TUid& CSendAsServer::EditUtilsPluginUid() const |
|
209 { |
|
210 return iEditUtilsPluginUid; |
|
211 } |
|
212 |
|
213 CMsvSession& CSendAsServer::GetMsvSessionL() |
|
214 { |
|
215 // if session has become lazy - create new session |
|
216 if (iMsvSession == NULL) |
|
217 { |
|
218 iMsvSession = CMsvSession::OpenSyncL(*this); |
|
219 } |
|
220 return *iMsvSession; |
|
221 } |
|
222 |
|
223 CSendAsMtmManager* CSendAsServer::GetMtmManager() |
|
224 { |
|
225 return iMtmManager; |
|
226 } |
|
227 |
|
228 /** Message Server Session Observer Callback. |
|
229 |
|
230 Used to keep track of the status of the message server. |
|
231 |
|
232 @param aEvent |
|
233 The message server event to be handled. |
|
234 */ |
|
235 void CSendAsServer::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/) |
|
236 { |
|
237 switch(aEvent) |
|
238 { |
|
239 case EMsvServerTerminated: |
|
240 case EMsvCloseSession: |
|
241 // close session (be lazy) |
|
242 delete iMsvSession; |
|
243 iMsvSession = NULL; |
|
244 break; |
|
245 case EMsvMtmGroupDeInstalled: |
|
246 case EMsvMtmGroupInstalled: |
|
247 // handle mtm installation/uninstallation |
|
248 HandleMtmChangeL(aEvent); |
|
249 break; |
|
250 case EMsvCorruptedIndexRebuilding: |
|
251 case EMsvCorruptedIndexRebuilt: |
|
252 // ignore |
|
253 case EMsvEntriesChanged: |
|
254 case EMsvEntriesCreated: |
|
255 case EMsvEntriesDeleted: |
|
256 case EMsvEntriesMoved: |
|
257 // don't care |
|
258 case EMsvGeneralError: |
|
259 // not used after v5 |
|
260 case EMsvMediaAvailable: |
|
261 case EMsvMediaChanged: |
|
262 case EMsvMediaIncorrect: |
|
263 case EMsvMediaUnavailable: |
|
264 // not to worry - appropriate errors will filter back to client |
|
265 case EMsvServerReady: |
|
266 case EMsvServerFailedToStart: |
|
267 // shouldn't happen since session is synchronously opened |
|
268 break; |
|
269 default: |
|
270 break; |
|
271 } |
|
272 } |
|
273 |
|
274 void CSendAsServer::HandleMtmChangeL(TMsvSessionEvent& aEvent) |
|
275 { |
|
276 // update the MTM manager |
|
277 iMtmManager->RefreshMtmUidArrayL(); |
|
278 |
|
279 // call each session's MTM Change handling method if a MTM has been de-installed |
|
280 if (aEvent == EMsvMtmGroupDeInstalled) |
|
281 { |
|
282 iSessionIter.SetToFirst(); |
|
283 CSendAsSession* ses = (CSendAsSession*)&(*iSessionIter++); |
|
284 while (ses!=NULL) |
|
285 { |
|
286 ses->HandleMtmChange(); |
|
287 ses = (CSendAsSession*)&(*(iSessionIter++)); |
|
288 } |
|
289 } |
|
290 } |