|
1 /* |
|
2 * Copyright (c) 2008 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 the License "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 "serviceinterface.h" |
|
20 |
|
21 // Including a copy of common constants for this compilation unit |
|
22 #include "serviceregistryservice.hrh" |
|
23 |
|
24 // Including utilities |
|
25 #include "serviceregistryutilities.h" |
|
26 |
|
27 #include "serviceregistryiterator.h" |
|
28 |
|
29 #include<hal.h> |
|
30 |
|
31 |
|
32 |
|
33 //constants for default and invalid versions |
|
34 const TReal KUnSpMaxVersion = 0.0; |
|
35 const TReal KDefaultMinVersion = 1.0; |
|
36 //thread name |
|
37 _LIT(KThreadName,"ListThread"); |
|
38 |
|
39 |
|
40 // ----------------------------------------------------------------------------- |
|
41 // CServiceInterface::NewLC |
|
42 // Returns the instance of CServiceInterface. |
|
43 // ----------------------------------------------------------------------------- |
|
44 // |
|
45 CServiceInterface* CServiceInterface::NewL() |
|
46 { |
|
47 CServiceInterface* self = new(ELeave) CServiceInterface(); |
|
48 CleanupStack::PushL(self); |
|
49 self->ConstructL(); |
|
50 CleanupStack::Pop(self); |
|
51 return self; |
|
52 } |
|
53 |
|
54 // ----------------------------------------------------------------------------- |
|
55 // CServiceInterface::~CServiceInterface |
|
56 // Destructor of class |
|
57 // ----------------------------------------------------------------------------- |
|
58 // |
|
59 CServiceInterface::~CServiceInterface() |
|
60 { |
|
61 Cancel(); |
|
62 iThread.Close(); |
|
63 delete iServiceHandler; |
|
64 iServiceHandler = NULL; |
|
65 |
|
66 delete iServiceName; |
|
67 iServiceName = NULL; |
|
68 |
|
69 delete iInterfaceName; |
|
70 iInterfaceName = NULL; |
|
71 } |
|
72 |
|
73 |
|
74 void CServiceInterface :: RCriteriaArrayCleanup(TAny* aParam) |
|
75 { |
|
76 RCriteriaArray* ptr = reinterpret_cast<RCriteriaArray*>(aParam); |
|
77 ptr->ResetAndDestroy(); |
|
78 delete ptr; |
|
79 } |
|
80 // ----------------------------------------------------------------------------- |
|
81 // CServiceInterface::ExecuteCmdL |
|
82 // Request handler method of interface class |
|
83 // ----------------------------------------------------------------------------- |
|
84 // |
|
85 void CServiceInterface::ExecuteCmdL(const TDesC8& aCmdName, |
|
86 const CLiwGenericParamList& aInParamList, |
|
87 CLiwGenericParamList& aOutParamList, |
|
88 TUint aCmdOptions , |
|
89 MLiwNotifyCallback* aCallBack) |
|
90 { |
|
91 TInt errCode(KErrNone); |
|
92 |
|
93 // Process the command. |
|
94 TRAP( errCode, ProcessCommandL(aCmdName, |
|
95 aInParamList, |
|
96 aOutParamList, |
|
97 aCmdOptions, |
|
98 aCallBack)); |
|
99 // Checking error code in here. |
|
100 // If any error has been occurred then it is inserted into output list. |
|
101 |
|
102 |
|
103 if(errCode != KErrNone) |
|
104 { |
|
105 TServiceRegistryUtilities utils; |
|
106 TLiwVariant retErrCode; |
|
107 retErrCode.Set(TInt32(utils.GetSapiErrorCode(errCode))); |
|
108 TLiwGenericParam errTypeParam(KErrorCode, retErrCode); |
|
109 aOutParamList.AppendL(errTypeParam); |
|
110 } |
|
111 } |
|
112 // ----------------------------------------------------------------------------- |
|
113 // CServiceInterface::ExecuteServiceCommandL |
|
114 // Request handler method of interface class |
|
115 // ----------------------------------------------------------------------------- |
|
116 // |
|
117 void CServiceInterface::ExecuteServiceCommandL(const TDesC8& aCmdName, |
|
118 const CLiwGenericParamList& aInParamList, |
|
119 CLiwGenericParamList& aOutParamList, |
|
120 TUint aCmdOptions , |
|
121 MLiwNotifyCallback* aCallBack) |
|
122 { |
|
123 ExecuteCmdL(aCmdName, |
|
124 aInParamList, |
|
125 aOutParamList, |
|
126 aCmdOptions, |
|
127 aCallBack); |
|
128 } |
|
129 |
|
130 |
|
131 // ----------------------------------------------------------------------------- |
|
132 // CServiceInterface::ProcessCommandL |
|
133 // Method that processes calls of interface class |
|
134 // ----------------------------------------------------------------------------- |
|
135 // |
|
136 void CServiceInterface::ProcessCommandL(const TDesC8& aCmdName, |
|
137 const CLiwGenericParamList& aInParamList, |
|
138 CLiwGenericParamList& aOutParamList, |
|
139 TUint aCmdOptions , |
|
140 MLiwNotifyCallback* aCallBack) |
|
141 { |
|
142 TInt32 transactionID(aCallBack->GetTransactionID()); |
|
143 |
|
144 if(aCmdName.CompareF(KGetList) == 0) |
|
145 { |
|
146 // If requesting asynchronous service |
|
147 if (aCmdOptions & KLiwOptASyncronous) // Asynchronous request |
|
148 { |
|
149 // Asynchronous request is supported |
|
150 if (aCallBack) // Callback object must be passed |
|
151 { |
|
152 GetListL(aInParamList, aOutParamList, transactionID, aCallBack); |
|
153 } |
|
154 else |
|
155 { |
|
156 // Asynchronous request did not have callback object available |
|
157 User::Leave(KErrArgument); |
|
158 } |
|
159 } |
|
160 else |
|
161 { |
|
162 // Synchronous request not supported for this method. |
|
163 User::Leave(KErrNotSupported); |
|
164 } |
|
165 }//GetList |
|
166 else if(aCmdName.CompareF(KCmdCancel) == 0) |
|
167 { |
|
168 // TServiceRegistryUtilities utility class instance |
|
169 TServiceRegistryUtilities utils; |
|
170 TInt32 transID(utils.ConvertInputInt32L(aInParamList, |
|
171 KTransactionId)); |
|
172 if(KLiwOptCancel & aCmdOptions) |
|
173 { |
|
174 if(transID != iTransactionId) |
|
175 { |
|
176 User::Leave(KErrNotFound); |
|
177 } |
|
178 Cancel(); |
|
179 aOutParamList.AppendL(TLiwGenericParam(KErrorCode, |
|
180 TLiwVariant((TInt32)SErrNone))); |
|
181 } |
|
182 else |
|
183 { |
|
184 User::Leave(KErrNotSupported); |
|
185 } |
|
186 }//Cancel |
|
187 else |
|
188 { |
|
189 User::Leave(KErrNotSupported);//Command is not supported |
|
190 } |
|
191 // Sending transaction ID back to the client in case of an successful asynchronous call |
|
192 if (aCallBack && aCmdOptions == KLiwOptASyncronous) |
|
193 { |
|
194 aOutParamList.AppendL(TLiwGenericParam(KTransactionId, |
|
195 TLiwVariant((TInt32)transactionID))); |
|
196 } |
|
197 } |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // CServiceInterface::CServiceInterface |
|
201 // Constructor of class |
|
202 // ----------------------------------------------------------------------------- |
|
203 // |
|
204 CServiceInterface::CServiceInterface() |
|
205 :CActive(EPriorityStandard), |
|
206 iTransactionId(0), |
|
207 iServiceName(NULL), |
|
208 iInterfaceName(NULL), |
|
209 iMinVersion(KUnSpMaxVersion), |
|
210 iMaxVersion(KUnSpMaxVersion), |
|
211 iInParamList(NULL), |
|
212 iServiceHandler(NULL) |
|
213 { |
|
214 CActiveScheduler::Add(this); |
|
215 } |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CServiceInterface::ConstructL |
|
219 // Two-phased constructor of class |
|
220 // ----------------------------------------------------------------------------- |
|
221 // |
|
222 void CServiceInterface::ConstructL() |
|
223 { |
|
224 iServiceHandler = CLiwServiceHandler :: NewL(); |
|
225 iServiceName = KNullDesC8().Alloc(); |
|
226 iInterfaceName = KNullDesC8().Alloc(); |
|
227 } |
|
228 |
|
229 // ----------------------------------------------------------------------------- |
|
230 // CServiceInterface::ListServiceProvidersL |
|
231 // This class is called once the async request is complete |
|
232 // It puts the iterator into the ouputlist and calls the HnadleNotifyL. |
|
233 // ----------------------------------------------------------------------------- |
|
234 // |
|
235 void CServiceInterface :: ListServiceProvidersL(TInt32 aError) |
|
236 { |
|
237 CLiwGenericParamList* eventParamList = CLiwGenericParamList::NewL(); |
|
238 CleanupStack::PushL(eventParamList); |
|
239 |
|
240 TInt event = KLiwEventError; |
|
241 |
|
242 eventParamList->AppendL(TLiwGenericParam(KErrorCode, |
|
243 TLiwVariant(aError))); |
|
244 if(aError == KErrNone) |
|
245 { |
|
246 event = KLiwEventCompleted; |
|
247 eventParamList->AppendL(TLiwGenericParam(KReturnValue, |
|
248 TLiwVariant(iIterator))); |
|
249 iIterator->DecRef(); |
|
250 } |
|
251 |
|
252 TRAPD(err, iCallback->HandleNotifyL((TInt32)iTransactionId, |
|
253 event, |
|
254 *eventParamList, |
|
255 *iInParamList)); |
|
256 |
|
257 //eventParamList->Reset(); |
|
258 CleanupStack::PopAndDestroy(eventParamList); |
|
259 } |
|
260 |
|
261 |
|
262 |
|
263 // ----------------------------------------------------------------------------- |
|
264 // This funtion runs as a part of the thread and fetches the list of providers |
|
265 // creates the iterator to the list. |
|
266 // ----------------------------------------------------------------------------- |
|
267 // |
|
268 |
|
269 void GetListProviderL(CServiceInterface* aInterface) |
|
270 { |
|
271 CLiwMap* pMetaDataMap = NULL; // map with key as "range" and value as a List |
|
272 CLiwList* pRangeList = NULL; |
|
273 RCriteriaArray* interest = new(ELeave) RCriteriaArray; |
|
274 RCriteriaArray* providerList = new(ELeave) RCriteriaArray; |
|
275 |
|
276 CleanupStack::PushL(TCleanupItem(CServiceInterface::RCriteriaArrayCleanup, interest)); |
|
277 CleanupStack::PushL(TCleanupItem(CServiceInterface::RCriteriaArrayCleanup, providerList)); |
|
278 |
|
279 if(aInterface->iServiceName->CompareF(KNullDesC8) == 0) |
|
280 { |
|
281 delete aInterface->iServiceName; |
|
282 aInterface->iServiceName = KWild().Alloc(); |
|
283 } |
|
284 if(aInterface->iInterfaceName->CompareF(KNullDesC8) == 0) |
|
285 { |
|
286 delete aInterface->iInterfaceName; |
|
287 aInterface->iInterfaceName = KWild().Alloc(); |
|
288 } |
|
289 |
|
290 //To Query for a list of all the LIW providers present. |
|
291 CLiwCriteriaItem* criteria = CLiwCriteriaItem::NewL(1, |
|
292 *aInterface->iInterfaceName, |
|
293 *aInterface->iServiceName); |
|
294 //delete the member variables so that they cab be used again |
|
295 // for the next call. |
|
296 |
|
297 delete aInterface->iServiceName; |
|
298 aInterface->iServiceName = KNullDesC8().Alloc(); |
|
299 delete aInterface->iInterfaceName; |
|
300 aInterface->iInterfaceName = KNullDesC8().Alloc(); |
|
301 |
|
302 CleanupStack::PushL(criteria); |
|
303 |
|
304 if(aInterface->iMinVersion != KUnSpMaxVersion || aInterface->iMaxVersion != KUnSpMaxVersion) |
|
305 { |
|
306 pMetaDataMap = CLiwDefaultMap::NewL(); // map with key as "range" and value as a List |
|
307 CleanupStack::PushL(pMetaDataMap); |
|
308 |
|
309 pRangeList = CLiwDefaultList::NewL(); // List where the values such as "ver" , minimum and maximum will be stored |
|
310 CleanupStack::PushL(pRangeList); |
|
311 |
|
312 pRangeList->AppendL(TLiwVariant(KVersion)); // "ver" is the string representing VERSION information in metadata |
|
313 |
|
314 pRangeList->AppendL(TLiwVariant(aInterface->iMinVersion)); // minimum range - The service should contain version only above this |
|
315 |
|
316 pRangeList->AppendL(TLiwVariant(aInterface->iMaxVersion)); // maximum range - The service should contain version only below this |
|
317 |
|
318 pMetaDataMap->InsertL(KRange, pRangeList); // "range" is set as key and the value is the List created above |
|
319 criteria->SetMetaDataOptions(pMetaDataMap); |
|
320 |
|
321 pRangeList->DecRef(); // Decrementing the reference of the List |
|
322 pMetaDataMap->DecRef(); // Decrementing the reference of the Map |
|
323 |
|
324 CleanupStack::Pop(pRangeList); |
|
325 CleanupStack::Pop(pMetaDataMap); |
|
326 } |
|
327 //reset the version members to unspecified. |
|
328 aInterface->iMinVersion = KUnSpMaxVersion; |
|
329 aInterface->iMaxVersion = KUnSpMaxVersion; |
|
330 |
|
331 //Presently this value is changed to differentiate LIW Providers from other Ecom plug-ins. |
|
332 criteria->SetServiceClass(TUid::Uid(KLiwClassBase)); |
|
333 |
|
334 interest->AppendL(criteria); |
|
335 CleanupStack::Pop(criteria); |
|
336 |
|
337 aInterface->iServiceHandler->QueryImplementationL(*interest, *providerList); |
|
338 |
|
339 aInterface->iIterator = CSvcRegIterator :: NewL(); |
|
340 |
|
341 aInterface->iIterator->SetProviderDataList(providerList); |
|
342 |
|
343 CleanupStack::Pop(providerList); |
|
344 CleanupStack::PopAndDestroy(interest); |
|
345 |
|
346 } |
|
347 |
|
348 |
|
349 // ----------------------------------------------------------------------------- |
|
350 // Thread Function which calls the GetListProviderL |
|
351 // ----------------------------------------------------------------------------- |
|
352 // |
|
353 TInt ThreadListProvider(TAny* aData) |
|
354 { |
|
355 CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack |
|
356 CServiceInterface* svcifc = reinterpret_cast<CServiceInterface*> (aData); |
|
357 TRAPD(err, GetListProviderL(svcifc)); |
|
358 delete cleanup; |
|
359 User::Exit(err); |
|
360 return 0; |
|
361 } |
|
362 |
|
363 // ----------------------------------------------------------------------------- |
|
364 // CServiceInterface::GetListL |
|
365 // Gets the list of ServiceProviders. |
|
366 // ----------------------------------------------------------------------------- |
|
367 // |
|
368 |
|
369 void CServiceInterface::GetListL(const CLiwGenericParamList& aInParamList, |
|
370 CLiwGenericParamList& aOutParamList, |
|
371 TInt32 aTransactionId, |
|
372 MLiwNotifyCallback* aCallBack) |
|
373 { |
|
374 TInt pos = 0; |
|
375 TLiwVariant minver; |
|
376 TLiwVariant maxver; |
|
377 TLiwVariant serviceName; |
|
378 TLiwVariant interfaceName; |
|
379 |
|
380 const CLiwMap* pMap = NULL; |
|
381 const TLiwGenericParam* paramFilterMap = NULL; |
|
382 |
|
383 iCallback = aCallBack; |
|
384 iTransactionId = aTransactionId; |
|
385 |
|
386 paramFilterMap = aInParamList.FindFirst(pos, KParamFilter); |
|
387 |
|
388 if(paramFilterMap) |
|
389 { |
|
390 pMap = paramFilterMap->Value().AsMap(); |
|
391 if(pMap) |
|
392 { |
|
393 if( pMap->FindL(KServiceName, serviceName)) |
|
394 { |
|
395 if ( serviceName.TypeId() != LIW::EVariantTypeDesC ) |
|
396 { |
|
397 serviceName.Reset(); |
|
398 User::Leave( KErrArgument ); |
|
399 } |
|
400 delete iServiceName; |
|
401 iServiceName = NULL; |
|
402 iServiceName = HBufC8::NewL(serviceName.AsDes().Length()); |
|
403 iServiceName->Des().Copy(serviceName.AsDes()); |
|
404 } |
|
405 if( pMap->FindL(KInterfaceName, interfaceName)) |
|
406 { |
|
407 if ( interfaceName.TypeId() != LIW::EVariantTypeDesC ) |
|
408 { |
|
409 serviceName.Reset(); |
|
410 interfaceName.Reset(); |
|
411 User::Leave( KErrArgument ); |
|
412 } |
|
413 delete iInterfaceName; |
|
414 iInterfaceName = NULL; |
|
415 iInterfaceName = HBufC8::NewL(interfaceName.AsDes().Length()); |
|
416 iInterfaceName->Des().Copy(interfaceName.AsDes()); |
|
417 } |
|
418 if( pMap->FindL(KMinVersion, minver)) |
|
419 { |
|
420 if ( minver.TypeId() != LIW::EVariantTypeTReal && minver.TypeId() != LIW::EVariantTypeTInt32) |
|
421 { |
|
422 minver.Reset(); |
|
423 serviceName.Reset(); |
|
424 interfaceName.Reset(); |
|
425 User::Leave( KErrArgument ); |
|
426 } |
|
427 iMinVersion = minver.AsTReal(); |
|
428 } |
|
429 if( pMap->FindL(KMaxVersion, maxver)) |
|
430 { |
|
431 if ( maxver.TypeId() != LIW::EVariantTypeTReal && maxver.TypeId() != LIW::EVariantTypeTInt32 ) |
|
432 { |
|
433 minver.Reset(); |
|
434 maxver.Reset(); |
|
435 serviceName.Reset(); |
|
436 interfaceName.Reset(); |
|
437 User::Leave( KErrArgument ); |
|
438 } |
|
439 iMaxVersion = maxver.AsTReal(); |
|
440 //set the min version to default only if max version is specified. |
|
441 if(iMinVersion == KUnSpMaxVersion) |
|
442 iMinVersion = KDefaultMinVersion; |
|
443 } |
|
444 if(iMaxVersion != KUnSpMaxVersion) |
|
445 { |
|
446 if(iMaxVersion < iMinVersion) |
|
447 { |
|
448 minver.Reset(); |
|
449 maxver.Reset(); |
|
450 serviceName.Reset(); |
|
451 interfaceName.Reset(); |
|
452 User::Leave(KErrArgument); |
|
453 } |
|
454 } |
|
455 } |
|
456 else |
|
457 { |
|
458 minver.Reset(); |
|
459 maxver.Reset(); |
|
460 serviceName.Reset(); |
|
461 interfaceName.Reset(); |
|
462 User::Leave(KErrArgument); |
|
463 } |
|
464 } |
|
465 minver.Reset(); |
|
466 maxver.Reset(); |
|
467 serviceName.Reset(); |
|
468 interfaceName.Reset(); |
|
469 |
|
470 if(!IsActive()) |
|
471 { |
|
472 User::LeaveIfError(iThread.Create(KThreadName, |
|
473 ThreadListProvider, |
|
474 KDefaultStackSize, |
|
475 &User::Allocator(), |
|
476 this)); |
|
477 } |
|
478 else |
|
479 { |
|
480 User::Leave(KErrInUse); |
|
481 } |
|
482 iStatus = KRequestPending; |
|
483 SetActive(); |
|
484 iThread.Resume(); |
|
485 iThread.Logon(iStatus); |
|
486 // append the error code to the outputlist. |
|
487 aOutParamList.AppendL(TLiwGenericParam(KErrorCode, |
|
488 TLiwVariant(TInt32(SErrNone)))); |
|
489 } |
|
490 |
|
491 void CServiceInterface :: DoCancel() |
|
492 { |
|
493 iThread.Kill(KErrNone); |
|
494 iThread.Close(); |
|
495 } |
|
496 |
|
497 |
|
498 void CServiceInterface :: RunL() |
|
499 { |
|
500 iThread.Close(); |
|
501 ListServiceProvidersL(iStatus.Int()); |
|
502 } |
|
503 |