|
1 /* |
|
2 * Copyright (c) 2003 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "CdlServer.h" |
|
20 |
|
21 const TInt KCdlSessionMaxBuf = 0x100000; // 1 megabyte limit on IPC transfers |
|
22 |
|
23 CCdlSession::CCdlSession() |
|
24 { |
|
25 } |
|
26 |
|
27 CCdlServer& CCdlSession::Server() |
|
28 { |
|
29 return *static_cast<CCdlServer*>(const_cast<CServer2*>(CSession2::Server())); |
|
30 } |
|
31 |
|
32 TBool CCdlSession::NotifyPending() const |
|
33 { |
|
34 return !iNotify.IsNull(); |
|
35 } |
|
36 |
|
37 void CCdlSession::CreateL() |
|
38 // |
|
39 // 2nd phase construct for sessions - called by the CServer2 framework |
|
40 // |
|
41 { |
|
42 Server().AddSession(); |
|
43 } |
|
44 |
|
45 CCdlSession::~CCdlSession() |
|
46 { |
|
47 delete iTempBuf; |
|
48 delete iSendingBuf; |
|
49 delete iSendingState; |
|
50 Server().DropSession(); |
|
51 } |
|
52 |
|
53 void CCdlSession::ServiceL(const RMessage2& aMessage) |
|
54 // |
|
55 // Handle a client request. |
|
56 // Leaving is handled by CCdlServer::RunError() which reports the error code |
|
57 // to the client |
|
58 // |
|
59 { |
|
60 switch (aMessage.Function()) |
|
61 { |
|
62 case ECdlServCmdRequestGetCust: |
|
63 RequestGetCustL(aMessage); |
|
64 break; |
|
65 |
|
66 case ECdlServCmdGetCust: |
|
67 GetCustL(aMessage); |
|
68 break; |
|
69 |
|
70 case ECdlServCmdSetUidsToNotify: |
|
71 SetUidsToNotifyL(aMessage); |
|
72 break; |
|
73 |
|
74 case ECdlServCmdNotifyChange: |
|
75 NotifyChangeL(aMessage); |
|
76 break; |
|
77 |
|
78 case ECdlServCmdCancelNotifyChange: |
|
79 CancelNotifyChangeL(aMessage); |
|
80 break; |
|
81 |
|
82 case ECdlServCmdSetCust: |
|
83 SetCustL(aMessage); |
|
84 break; |
|
85 |
|
86 case ECdlServCmdGetRefsSize: |
|
87 GetRefsSizeL(aMessage); |
|
88 break; |
|
89 |
|
90 case ECdlServCmdGetNamesSize: |
|
91 GetNamesSizeL(aMessage); |
|
92 break; |
|
93 |
|
94 case ECdlServCmdGetTempBuf: |
|
95 GetTempBufL(aMessage); |
|
96 break; |
|
97 |
|
98 case ECdlServCmdGetAllRefsSize: |
|
99 GetAllRefsSizeL(aMessage); |
|
100 break; |
|
101 |
|
102 case ECdlServCmdIsPluginInRom: |
|
103 IsPluginInRomL(aMessage); |
|
104 break; |
|
105 |
|
106 case ECdlServCmdPluginDrive: |
|
107 PluginDriveL(aMessage); |
|
108 break; |
|
109 |
|
110 default: |
|
111 PanicClient(aMessage,EPanicIllegalFunction); |
|
112 break; |
|
113 } |
|
114 } |
|
115 |
|
116 void CCdlSession::RequestGetCustL(const RMessage2& aMessage) |
|
117 { |
|
118 if (iSendingBuf) |
|
119 { |
|
120 aMessage.Complete(KErrNotReady); |
|
121 return; |
|
122 } |
|
123 |
|
124 // get the uids from the client |
|
125 CCdlUids* uids = CCdlUids::NewLC(); |
|
126 HBufC8* buf = HBufC8::NewMaxLC(ValidIntL(aMessage.Int2(), 0, KCdlSessionMaxBuf)); |
|
127 TPtr8 ptr = buf->Des(); |
|
128 aMessage.ReadL(1, ptr); |
|
129 uids->ImportL(*buf); |
|
130 CleanupStack::PopAndDestroy(buf); |
|
131 |
|
132 // get the size of the requested customisation |
|
133 delete iSendingState; |
|
134 iSendingState = 0; |
|
135 delete iSendingBuf; |
|
136 iSendingBuf = 0; |
|
137 CCdlRefs* sendingState = Server().GetStateLC(*uids); |
|
138 iSendingBuf = sendingState->ExportL(); |
|
139 iSendingState = sendingState; |
|
140 TInt size=iSendingBuf->Size(); |
|
141 CleanupStack::Pop(sendingState); |
|
142 CleanupStack::PopAndDestroy(uids); |
|
143 |
|
144 // send the size to the client |
|
145 TPckg<TInt> sizePckg(size); |
|
146 WriteAndComplete(aMessage, 0, sizePckg); |
|
147 } |
|
148 |
|
149 void CCdlSession::GetCustL(const RMessage2& aMessage) |
|
150 { |
|
151 if (!iSendingBuf) |
|
152 { |
|
153 PanicClient(aMessage, EPanicNoCustomisationRequested); |
|
154 return; |
|
155 } |
|
156 |
|
157 if (iSendingBuf->Size() > aMessage.Int1()) |
|
158 { |
|
159 TInt size=iSendingBuf->Size(); |
|
160 TPckg<TInt> sizePckg(size); |
|
161 WriteAndComplete(aMessage, 2, sizePckg, KCdlRefsSizeChanged); |
|
162 return; |
|
163 } |
|
164 |
|
165 WriteAndComplete(aMessage, 0, *iSendingBuf); |
|
166 delete iSendingBuf; |
|
167 iSendingBuf = 0; |
|
168 delete iSendingState; |
|
169 iSendingState = 0; |
|
170 iQueuedCustChange = EFalse; |
|
171 } |
|
172 |
|
173 void CCdlSession::SetUidsToNotifyL(const RMessage2& aMessage) |
|
174 { |
|
175 HBufC8* buf = HBufC8::NewMaxLC(ValidIntL(aMessage.Int1(), 0, KCdlSessionMaxBuf)); |
|
176 TPtr8 ptr = buf->Des(); |
|
177 aMessage.ReadL(0, ptr); |
|
178 iUids.ImportL(*buf); |
|
179 CleanupStack::PopAndDestroy(buf); |
|
180 aMessage.Complete(KErrNone); |
|
181 } |
|
182 |
|
183 void CCdlSession::NotifyChangeL(const RMessage2& aMessage) |
|
184 { |
|
185 if (NotifyPending()) |
|
186 PanicClient(aMessage,EPanicNotifyActive); |
|
187 else |
|
188 iNotify=aMessage; |
|
189 |
|
190 if (iQueuedCustChange) |
|
191 { |
|
192 NotifyCustChangeL(); |
|
193 } |
|
194 else if (iQueuedRefsChange) |
|
195 { |
|
196 HandleRefsChangeL(); |
|
197 } |
|
198 } |
|
199 |
|
200 void CCdlSession::CancelNotifyChangeL(const RMessage2& aMessage) |
|
201 { |
|
202 if (NotifyPending()) |
|
203 iNotify.Complete(KErrCancel); |
|
204 aMessage.Complete(KErrNone); |
|
205 } |
|
206 |
|
207 void CCdlSession::SetCustL(const RMessage2& aMessage) |
|
208 { |
|
209 CCdlRefs* state = CCdlRefs::NewLC(); |
|
210 HBufC8* buf = HBufC8::NewMaxLC(ValidIntL(aMessage.Int1(), 0, KCdlSessionMaxBuf)); |
|
211 TPtr8 ptr = buf->Des(); |
|
212 aMessage.ReadL(0, ptr); |
|
213 state->ImportL(*buf); |
|
214 CleanupStack::PopAndDestroy(buf); |
|
215 Server().SetStateL(state); |
|
216 CleanupStack::PopAndDestroy(state); |
|
217 aMessage.Complete(KErrNone); |
|
218 } |
|
219 |
|
220 void CCdlSession::NotifyCustChangeL() |
|
221 { |
|
222 if (NotifyPending()) |
|
223 { |
|
224 TPckgBuf<SCdlServerChange> change; |
|
225 change().iType = SCdlServerChange::EGlobalCustomisation; |
|
226 change().iSize = iSendingBuf->Size(); |
|
227 WriteAndComplete(iNotify, 0, change); |
|
228 iQueuedCustChange = EFalse; |
|
229 } |
|
230 else |
|
231 { |
|
232 iQueuedCustChange = ETrue; |
|
233 } |
|
234 } |
|
235 |
|
236 void CCdlSession::WriteAndComplete(const RMessagePtr2& aMessage, TInt aParam, const TDesC8& aDes, TInt aCode) |
|
237 { |
|
238 TRAPD(r,aMessage.WriteL(aParam, aDes)); |
|
239 if (r==KErrNone) |
|
240 aMessage.Complete(aCode); |
|
241 else |
|
242 PanicClient(aMessage, EPanicBadDescriptor); |
|
243 } |
|
244 |
|
245 void CCdlSession::HandleCustChangeL(const CCdlUids& aUids) |
|
246 { |
|
247 CCdlUids* change = iUids.IntersectionLC(aUids); |
|
248 if (change->Count()) |
|
249 { |
|
250 if (iSendingBuf == NULL) |
|
251 { |
|
252 iSendingState = Server().GetStateLC(*change); |
|
253 CleanupStack::Pop(iSendingState); |
|
254 iSendingBuf = iSendingState->ExportL(); |
|
255 NotifyCustChangeL(); |
|
256 } |
|
257 else |
|
258 { |
|
259 iSendingState->MergeAndReplaceL(*Server().GetStateLC(*change)); |
|
260 CleanupStack::PopAndDestroy(); // change in state; |
|
261 delete iSendingBuf; |
|
262 iSendingBuf = 0; |
|
263 iSendingBuf = iSendingState->ExportL(); |
|
264 // don't notify change in state for ongoing transaction |
|
265 } |
|
266 } |
|
267 |
|
268 CleanupStack::PopAndDestroy(change); |
|
269 } |
|
270 |
|
271 void CCdlSession::HandleRefsChangeL() |
|
272 { |
|
273 if (NotifyPending()) |
|
274 { |
|
275 TPckgBuf<SCdlServerChange> change; |
|
276 change().iType = SCdlServerChange::EAvailableRefs; |
|
277 WriteAndComplete(iNotify, 0, change); |
|
278 iQueuedRefsChange = EFalse; |
|
279 } |
|
280 else |
|
281 { |
|
282 iQueuedRefsChange = ETrue; |
|
283 } |
|
284 } |
|
285 |
|
286 void CCdlSession::GetRefsSizeL(const RMessage2& aMessage) |
|
287 { |
|
288 delete iTempBuf; |
|
289 iTempBuf = 0; |
|
290 |
|
291 if (aMessage.Int1()) // Get by name |
|
292 { |
|
293 HBufC* buf = HBufC::NewMaxLC(ValidIntL(aMessage.Int2(), 0, KMaxFileName)); |
|
294 TPtr ptr = buf->Des(); |
|
295 aMessage.ReadL(1, ptr); |
|
296 CCdlRefs* refs = Server().AllRefs().SubsetByNameLC(*buf); |
|
297 if (refs->CountRefs() == 0) // library not found in server, perhaps not scanned yet. |
|
298 { |
|
299 CCdlRefCollection* contents = Server().FileContentsLC(*buf); |
|
300 refs->AppendL(*contents); |
|
301 CleanupStack::PopAndDestroy(contents); |
|
302 } |
|
303 iTempBuf = refs->ExportL(); |
|
304 CleanupStack::PopAndDestroy(refs); |
|
305 CleanupStack::PopAndDestroy(buf); |
|
306 } |
|
307 else // Get by UID |
|
308 { |
|
309 iTempBuf = Server().AllRefs().SubsetByUidLC(TUid::Uid(aMessage.Int3()))->ExportL(); |
|
310 CleanupStack::PopAndDestroy(); // unnamed CCdlRefs |
|
311 } |
|
312 |
|
313 // send the size to the client |
|
314 TPckgBuf<TInt> sizePckg(iTempBuf->Size()); |
|
315 WriteAndComplete(aMessage, 0, sizePckg); |
|
316 } |
|
317 |
|
318 void CCdlSession::GetAllRefsSizeL(const RMessage2& aMessage) |
|
319 { |
|
320 delete iTempBuf; |
|
321 iTempBuf = 0; |
|
322 iTempBuf = Server().AllRefs().ExportL(); |
|
323 |
|
324 // send the size to the client |
|
325 TPckgBuf<TInt> sizePckg(iTempBuf->Size()); |
|
326 WriteAndComplete(aMessage, 0, sizePckg); |
|
327 } |
|
328 |
|
329 void CCdlSession::GetNamesSizeL(const RMessage2& aMessage) |
|
330 { |
|
331 delete iTempBuf; |
|
332 iTempBuf = 0; |
|
333 iTempBuf = Server().AllRefs().Names().ExportL(); |
|
334 |
|
335 // send the size to the client |
|
336 TPckgBuf<TInt> sizePckg(iTempBuf->Size()); |
|
337 WriteAndComplete(aMessage, 0, sizePckg); |
|
338 } |
|
339 |
|
340 void CCdlSession::GetTempBufL(const RMessage2& aMessage) |
|
341 { |
|
342 if (iTempBuf) |
|
343 { |
|
344 WriteAndComplete(aMessage, 0, *iTempBuf); |
|
345 delete iTempBuf; |
|
346 iTempBuf = 0; |
|
347 } |
|
348 else |
|
349 { |
|
350 // This message can only be used after one of the messages that |
|
351 // set up iTempBuf |
|
352 PanicClient(aMessage, EPanicBufRequestedWithoutSetup); |
|
353 } |
|
354 } |
|
355 |
|
356 void CCdlSession::IsPluginInRomL(const RMessage2& aMessage) |
|
357 { |
|
358 HBufC* fileBuf = HBufC::NewMaxLC(ValidIntL(aMessage.Int1(), 0, KMaxFileName)); |
|
359 TPtr filePtr = fileBuf->Des(); |
|
360 aMessage.ReadL(0, filePtr); |
|
361 |
|
362 TPckgBuf<TBool> isInRomPckg(EFalse); |
|
363 TInt err = Server().IsPluginInRom(*fileBuf, isInRomPckg()); |
|
364 CleanupStack::PopAndDestroy(fileBuf); |
|
365 |
|
366 WriteAndComplete(aMessage, 2, isInRomPckg, err); |
|
367 } |
|
368 |
|
369 void CCdlSession::PluginDriveL(const RMessage2& aMessage) |
|
370 { |
|
371 HBufC* fileBuf = HBufC::NewMaxLC(ValidIntL(aMessage.Int1(), 0, KMaxFileName)); |
|
372 TPtr filePtr = fileBuf->Des(); |
|
373 aMessage.ReadL(0, filePtr); |
|
374 |
|
375 TDriveUnit drive; |
|
376 TInt err = Server().PluginDrive(*fileBuf, drive); |
|
377 CleanupStack::PopAndDestroy(fileBuf); |
|
378 |
|
379 aMessage.Complete(err ? err : static_cast<TInt>(drive)); |
|
380 } |
|
381 |
|
382 TInt CCdlSession::ValidIntL(TInt aVal, TInt aMin, TInt aMax) const |
|
383 { |
|
384 if (aVal < aMin || aMax < aVal) |
|
385 { |
|
386 User::Leave(KErrArgument); |
|
387 } |
|
388 return aVal; |
|
389 } |
|
390 |