1 /* |
|
2 * Copyright (c) 2009 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 "SamplerController.h" |
|
20 #include <piprofiler/EngineUIDs.h> |
|
21 |
|
22 // CONSTANTS |
|
23 const TInt KMaxSamplerPluginCount = 20; |
|
24 const TInt KMaxExtraSettingsItemCount = 6; |
|
25 |
|
26 // LITERALS |
|
27 _LIT8(KEnabled, "enabled"); |
|
28 _LIT8(KSamplingPeriod, "sampling_period_ms"); |
|
29 _LIT8(KBracketOpen, "["); |
|
30 _LIT8(KBracketClose, "]"); |
|
31 _LIT8(KNewLine8, "\n"); |
|
32 _LIT8(KEquals8, "="); |
|
33 _LIT8(KSettingsText, " settings"); |
|
34 _LIT(KNewLine, "\n"); |
|
35 _LIT(KEquals, "="); |
|
36 _LIT(KCommentSeparator, " ; "); |
|
37 |
|
38 CSamplerController* CSamplerController::NewL(CProfilerSampleStream& aStream) |
|
39 { |
|
40 CSamplerController* self = new( ELeave ) CSamplerController(aStream); |
|
41 CleanupStack::PushL( self ); |
|
42 self->ConstructL( ); |
|
43 CleanupStack::Pop( self ); |
|
44 return self; |
|
45 } |
|
46 |
|
47 void CSamplerController::ConstructL() |
|
48 { |
|
49 // initiate sampler plugin list |
|
50 InitialiseSamplerListL(); |
|
51 } |
|
52 |
|
53 |
|
54 CSamplerController::CSamplerController(CProfilerSampleStream& aStream) : |
|
55 iStream(aStream) |
|
56 { |
|
57 } |
|
58 |
|
59 void CSamplerController::InitialiseSamplerListL() |
|
60 { |
|
61 // create new sampler plugin array |
|
62 iPluginArray = new (ELeave) CArrayPtrFlat<CSamplerPluginInterface>( KMaxSamplerPluginCount ); |
|
63 |
|
64 // create plugin loader instance |
|
65 iPluginLoader = CSamplerPluginLoader::NewL(); |
|
66 |
|
67 // register sampler controller to get notifications of succesfull plugin load |
|
68 iPluginLoader->SetObserver( this ); |
|
69 |
|
70 // load sampler plugins asynchronously |
|
71 iPluginLoader->LoadAsyncL( iPluginArray ); |
|
72 |
|
73 LOGTEXT(_L(" RSamplerController::InitialiseUserSideSamplerList - exit")); |
|
74 } |
|
75 |
|
76 CSamplerController::~CSamplerController() |
|
77 { |
|
78 LOGTEXT(_L("CSamplerController::~CSamplerController - entry" )); |
|
79 |
|
80 if ( iPluginArray ) |
|
81 { |
|
82 // destroy the plugin instances |
|
83 // empty loaded plugins from array |
|
84 for(TInt i(0);i<iPluginArray->Count();i++) |
|
85 { |
|
86 if(iPluginArray->At(i)) |
|
87 { |
|
88 delete iPluginArray->At(i); |
|
89 iPluginArray->At(i) = NULL; |
|
90 } |
|
91 } |
|
92 iPluginArray->Reset(); |
|
93 delete iPluginArray; |
|
94 iPluginArray = NULL; |
|
95 } |
|
96 |
|
97 if ( iPluginLoader ) |
|
98 { |
|
99 iPluginLoader->AbortAsyncLoad(); |
|
100 delete iPluginLoader; |
|
101 iPluginLoader = NULL; |
|
102 } |
|
103 |
|
104 LOGTEXT(_L("CSamplerController::~CSamplerController - exit" )); |
|
105 } |
|
106 |
|
107 void CSamplerController::SetObserver(MSamplerControllerObserver* aObserver) |
|
108 { |
|
109 iObserver = aObserver; |
|
110 } |
|
111 |
|
112 TInt CSamplerController::UpdateSavedSamplerAttributesL(CDesC8ArrayFlat* aSavedLineArray, CArrayFixFlat<TSamplerAttributes>* aAttributes) |
|
113 { |
|
114 TInt err(KErrNone); |
|
115 TInt count(iPluginArray->Count()); |
|
116 // all plugins get their own settings among whole lump of setting strings |
|
117 CSamplerPluginInterface* plugin = NULL; |
|
118 |
|
119 // loop through the plugin array |
|
120 for(TInt i(0);i<count;i++) |
|
121 { |
|
122 // get each plugin at a time |
|
123 plugin = iPluginArray->At(i); |
|
124 |
|
125 // call each plugin to sort out its own settings |
|
126 err = plugin->ConvertRawSettingsToAttributes(aSavedLineArray); |
|
127 |
|
128 // get plugin specific attributes, array may contain attributes of several sub samplers |
|
129 plugin->GetAttributesL(aAttributes); |
|
130 } |
|
131 |
|
132 return err; |
|
133 } |
|
134 |
|
135 TInt CSamplerController::SetSamplerSettingsL(TInt aUid, TSamplerAttributes aAttributes) |
|
136 { |
|
137 // parse right plugin based on UID |
|
138 CSamplerPluginInterface* plugin = GetPlugin(TUid::Uid(aUid)); |
|
139 |
|
140 // set the sampler attributes of a sampler plugin |
|
141 plugin->SetAttributesL(aAttributes); |
|
142 |
|
143 return KErrNone; |
|
144 } |
|
145 |
|
146 void CSamplerController::GetSamplerAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes) |
|
147 { |
|
148 CSamplerPluginInterface* plugin = NULL; |
|
149 |
|
150 TInt count(iPluginArray->Count()); |
|
151 |
|
152 // get first all the attributes from all the sampler plugins listed in iPluginArray |
|
153 for(TInt i(0);i<count;i++) |
|
154 { |
|
155 // get the plugin first |
|
156 plugin = iPluginArray->At(i); |
|
157 |
|
158 // get plugin specific attributes, array may contain attributes of several sub samplers |
|
159 plugin->GetAttributesL(aAttributes); |
|
160 } |
|
161 } |
|
162 |
|
163 void CSamplerController::ComposeAttributesToSettingsFileFormat(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttributes) |
|
164 { |
|
165 // write immediately to settings file |
|
166 ComposeSettingsText(aFile, aAttributes); |
|
167 } |
|
168 |
|
169 void CSamplerController::ComposeSettingsText(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttrArray) |
|
170 { |
|
171 // temporary buffer for a setting line |
|
172 TBuf<384> settingLine; |
|
173 TBuf8<384> settingLine8; |
|
174 TInt itemCount(0); |
|
175 TBuf<266> tBuf; |
|
176 |
|
177 TSamplerAttributes attr; |
|
178 |
|
179 for(TInt i(0);i<aAttrArray->Count();i++) |
|
180 { |
|
181 // get the attribute container |
|
182 attr = aAttrArray->At(i); |
|
183 |
|
184 // add the name and description of the sampler in brackets first |
|
185 settingLine8.Copy(KBracketOpen); |
|
186 settingLine8.Append(attr.iShortName); |
|
187 settingLine8.Append(KBracketClose); |
|
188 settingLine8.Append(KCommentSeparator()); |
|
189 settingLine8.Append(attr.iName); |
|
190 settingLine8.Append(KSettingsText); |
|
191 settingLine8.Append(KNewLine8); |
|
192 aFile.Write(settingLine8); |
|
193 |
|
194 // enabled |
|
195 settingLine8.Copy(KEnabled); |
|
196 settingLine8.Append(KEquals8); |
|
197 settingLine8.Append(Bool2Str(attr.iEnabled)); |
|
198 settingLine8.Append(KNewLine8); |
|
199 aFile.Write(settingLine8); |
|
200 |
|
201 // sampling rate (if set) |
|
202 if( attr.iSampleRate != -1 ) |
|
203 { |
|
204 settingLine8.Copy(KSamplingPeriod); |
|
205 settingLine8.Append(KEquals8); |
|
206 settingLine8.Append(Int2Str(attr.iSampleRate)); |
|
207 settingLine8.Append(KNewLine8); |
|
208 aFile.Write(settingLine8); |
|
209 } |
|
210 |
|
211 itemCount = attr.iItemCount; |
|
212 |
|
213 // check if item count set is sane, max extra settings item count 6 |
|
214 if(itemCount > KMaxExtraSettingsItemCount) |
|
215 { |
|
216 // probably forgot to set the item count value in plugin => safe to set it 0 |
|
217 itemCount = 0; |
|
218 } |
|
219 |
|
220 // setting items |
|
221 for (TInt j(0);j<itemCount;j++) |
|
222 { |
|
223 switch(j) |
|
224 { |
|
225 case 0: // settingItem1 |
|
226 { |
|
227 settingLine.Copy(attr.iSettingItem1.iSettingText); |
|
228 settingLine.Append(KEquals()); |
|
229 settingLine.Append(attr.iSettingItem1.iValue); |
|
230 settingLine.Append(KCommentSeparator()); |
|
231 settingLine.Append(attr.iSettingItem1.iUIText); |
|
232 settingLine.Append(KNewLine()); |
|
233 CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine); |
|
234 aFile.Write(settingLine8); |
|
235 break; |
|
236 } |
|
237 case 1: // settingItem2 |
|
238 { |
|
239 settingLine.Copy(attr.iSettingItem2.iSettingText); |
|
240 settingLine.Append(KEquals()); |
|
241 settingLine.Append(attr.iSettingItem2.iValue); |
|
242 settingLine.Append(KCommentSeparator()); |
|
243 settingLine.Append(attr.iSettingItem2.iUIText); |
|
244 settingLine.Append(KNewLine()); |
|
245 CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine); |
|
246 aFile.Write(settingLine8); |
|
247 break; |
|
248 } |
|
249 case 2: // settingItem3 |
|
250 { |
|
251 settingLine.Copy(attr.iSettingItem3.iSettingText); |
|
252 settingLine.Append(KEquals()); |
|
253 settingLine.Append(attr.iSettingItem3.iValue); |
|
254 settingLine.Append(KCommentSeparator()); |
|
255 settingLine.Append(attr.iSettingItem3.iUIText); |
|
256 settingLine.Append(KNewLine()); |
|
257 CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine); |
|
258 aFile.Write(settingLine8); |
|
259 break; |
|
260 } |
|
261 case 3: // settingItem4 |
|
262 { |
|
263 settingLine.Copy(attr.iSettingItem4.iSettingText); |
|
264 settingLine.Append(KEquals()); |
|
265 settingLine.Append(attr.iSettingItem4.iValue); |
|
266 settingLine.Append(KCommentSeparator()); |
|
267 settingLine.Append(attr.iSettingItem4.iUIText); |
|
268 settingLine.Append(KNewLine()); |
|
269 CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine); |
|
270 aFile.Write(settingLine8); |
|
271 break; |
|
272 } |
|
273 case 4: // settingItem5 |
|
274 { |
|
275 settingLine.Copy(attr.iSettingItem5.iSettingText); |
|
276 settingLine.Append(KEquals()); |
|
277 settingLine.Append(attr.iSettingItem5.iValue); |
|
278 settingLine.Append(KCommentSeparator()); |
|
279 settingLine.Append(attr.iSettingItem5.iUIText); |
|
280 settingLine.Append(KNewLine()); |
|
281 CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine); |
|
282 aFile.Write(settingLine8); |
|
283 break; |
|
284 } |
|
285 case 5: // settingItem6 |
|
286 { |
|
287 settingLine.Copy(attr.iSettingItem6.iSettingText); |
|
288 settingLine.Append(KEquals()); |
|
289 settingLine.Append(attr.iSettingItem6.iValue); |
|
290 settingLine.Append(KCommentSeparator()); |
|
291 settingLine.Append(attr.iSettingItem6.iUIText); |
|
292 settingLine.Append(KNewLine()); |
|
293 CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine); |
|
294 aFile.Write(settingLine8); |
|
295 break; |
|
296 } |
|
297 } |
|
298 } |
|
299 } |
|
300 } |
|
301 |
|
302 // ---------------------------------------------------------------------------- |
|
303 // Converts given descriptor into TBool value. |
|
304 // ---------------------------------------------------------------------------- |
|
305 // |
|
306 inline void CSamplerController::Str2Bool(const TDesC8& aBuf, TBool& aValue) |
|
307 { |
|
308 if (aBuf.CompareF(KFalse) == 0) |
|
309 aValue = EFalse; |
|
310 else |
|
311 aValue = ETrue; |
|
312 } |
|
313 |
|
314 // ---------------------------------------------------------------------------- |
|
315 // Converts given descriptor into TInt value. |
|
316 // ---------------------------------------------------------------------------- |
|
317 // |
|
318 inline void CSamplerController::Str2Int(const TDesC8& aBuf, TInt& aValue) |
|
319 { |
|
320 TLex8 conv; |
|
321 conv.Assign(aBuf); |
|
322 |
|
323 if (conv.Val(aValue) != KErrNone) |
|
324 aValue = 0; |
|
325 } |
|
326 |
|
327 // ---------------------------------------------------------------------------- |
|
328 // Converts given descriptor into TInt value. |
|
329 // ---------------------------------------------------------------------------- |
|
330 // |
|
331 inline void CSamplerController::Str2Int(const TDesC8& aBuf, TUint32& aValue) |
|
332 { |
|
333 TInt temp(0); |
|
334 |
|
335 TLex8 conv; |
|
336 conv.Assign(aBuf); |
|
337 |
|
338 if (conv.Val(temp) != KErrNone) |
|
339 aValue = 0; |
|
340 else |
|
341 aValue = (TUint32)temp; |
|
342 } |
|
343 |
|
344 // ---------------------------------------------------------------------------- |
|
345 // Converts given boolean into a descriptor. |
|
346 // ---------------------------------------------------------------------------- |
|
347 // |
|
348 inline TBuf8<16> CSamplerController::Bool2Str(const TBool& aValue) |
|
349 { |
|
350 TBuf8<16> buf; |
|
351 |
|
352 if (aValue) |
|
353 buf.Copy(KTrue); |
|
354 else |
|
355 buf.Copy(KFalse); |
|
356 |
|
357 return buf; |
|
358 } |
|
359 |
|
360 // ---------------------------------------------------------------------------- |
|
361 // Converts given integer into a descriptor. |
|
362 // ---------------------------------------------------------------------------- |
|
363 // |
|
364 inline TBuf8<16> CSamplerController::Int2Str(const TInt& aValue) |
|
365 { |
|
366 TBuf8<16> buf; |
|
367 buf.AppendNum(aValue); |
|
368 |
|
369 return buf; |
|
370 } |
|
371 |
|
372 |
|
373 void CSamplerController::HandlePluginLoaded( KSamplerPluginLoaderStatus aStatus ) |
|
374 { |
|
375 |
|
376 // process status value |
|
377 switch(aStatus) |
|
378 { |
|
379 case 0: |
|
380 LOGSTRING2("RSamplerController - one plugin loaded, status: %d", aStatus); |
|
381 break; |
|
382 case 1: |
|
383 LOGSTRING2("RSamplerController - a plugin load failed: %d", aStatus); |
|
384 break; |
|
385 case 2: |
|
386 LOGSTRING2("RSamplerController - plugin loading aborted: %d", aStatus); |
|
387 break; |
|
388 case 3: |
|
389 LOGSTRING2("RSamplerController - all plugins loaded: %d", aStatus); |
|
390 TRAPD(err, iPluginLoader->SortPluginsL(iPluginArray)); |
|
391 if(err != KErrNone) |
|
392 { |
|
393 LOGTEXT(_L("Sampler controller unable to sort plugins")); |
|
394 } |
|
395 |
|
396 // call engine to finalize the startup |
|
397 TRAPD(result, iObserver->HandleSamplerControllerReadyL();); |
|
398 if(result != KErrNone) |
|
399 { |
|
400 LOGTEXT(_L("Failed to notify engine")); |
|
401 } |
|
402 break; |
|
403 case 4: |
|
404 LOGSTRING2("RSamplerController - error in loading plugins: %d", aStatus); |
|
405 break; |
|
406 default: |
|
407 break; |
|
408 } |
|
409 } |
|
410 |
|
411 TUid CSamplerController::GetPluginUID(TDesC8& aName) |
|
412 { |
|
413 TUid uid; |
|
414 TInt id; |
|
415 |
|
416 // check if plugin array contains loaded samplers |
|
417 if( iPluginArray && iPluginArray->Count() > 0 ) |
|
418 { |
|
419 for(TInt i=0;i<iPluginArray->Count();i++) |
|
420 { |
|
421 CSamplerPluginInterface* plugin = iPluginArray->At(i); |
|
422 id = (TUint32)plugin->GetSamplerUidByName(aName); |
|
423 if(id != KErrNotFound) |
|
424 { |
|
425 return TUid::Uid(id); |
|
426 } |
|
427 } |
|
428 } |
|
429 |
|
430 LOGSTRING2(" RSamplerController::GetPluginUID - KErrNotFound! traceId = %d", id ); |
|
431 uid = TUid::Uid(0); |
|
432 return uid; |
|
433 } |
|
434 |
|
435 |
|
436 CSamplerPluginInterface* CSamplerController::GetPlugin(TUid aUid) |
|
437 { |
|
438 LOGTEXT(_L("RSamplerController::GetPlugin - entry")); |
|
439 // check that plugin array contains samplers |
|
440 if( iPluginArray && iPluginArray->Count() > 0 ) |
|
441 { |
|
442 for(TInt i=0;i<iPluginArray->Count();i++) |
|
443 { |
|
444 CSamplerPluginInterface* plugin = iPluginArray->At(i); |
|
445 TUid uid = plugin->Id(-1); // get parent uid first |
|
446 if(uid == aUid) |
|
447 { |
|
448 LOGTEXT(_L("CSamplerController::GetPlugin() - main plug-in found!")); |
|
449 return plugin; |
|
450 } |
|
451 |
|
452 if(plugin->SubId(aUid) != KErrNotFound) |
|
453 { |
|
454 LOGTEXT(_L("CSamplerController::GetPlugin() - subsampler found!")); |
|
455 return plugin; |
|
456 } |
|
457 } |
|
458 } |
|
459 LOGTEXT(_L("CSamplerController::GetPlugin() - No plug-in found for UID")); |
|
460 |
|
461 return (CSamplerPluginInterface*)0; |
|
462 } |
|
463 |
|
464 // start user mode samplers |
|
465 void CSamplerController::StartSamplerPluginsL() |
|
466 { |
|
467 CSamplerPluginInterface* plugin = NULL; |
|
468 TInt count(iPluginArray->Count()); |
|
469 TInt err(KErrNone); |
|
470 |
|
471 LOGSTRING2(" RSamplerController::StartSamplerPlugin - plugins loaded, amount = %d", count); |
|
472 if( iPluginArray && count > 0 ) |
|
473 { |
|
474 for(TInt i(0);i<count;i++) |
|
475 { |
|
476 plugin = iPluginArray->At(i); |
|
477 // check if some error received when starting profiling |
|
478 err = plugin->ResetAndActivateL(iStream); |
|
479 if( err != KErrNone) |
|
480 { |
|
481 // handle received error, need to update UI! |
|
482 iObserver->HandleError(err); |
|
483 } |
|
484 } |
|
485 } |
|
486 } |
|
487 |
|
488 // stop user mode samplers |
|
489 TInt CSamplerController::StopSamplerPlugins() |
|
490 { |
|
491 TInt count(0); |
|
492 |
|
493 if( iPluginArray && iPluginArray->Count() > 0 ) |
|
494 { |
|
495 TInt i(0); |
|
496 CSamplerPluginInterface* plugin = NULL; |
|
497 // stop kernel mode samplers |
|
498 for(;i<iPluginArray->Count();i++) |
|
499 { |
|
500 plugin = iPluginArray->At(i); |
|
501 TUint32 id = plugin->Id(-1).iUid; |
|
502 LOGSTRING2(" CSamplerController::StopSamplerPlugins - traceId = %d", |
|
503 id); |
|
504 // stop only started samplers |
|
505 if(plugin->Enabled()) |
|
506 { |
|
507 // stop selected plugin |
|
508 plugin->StopSampling(); |
|
509 // check if user mode sampler, special flush needed to direct data to stream |
|
510 if(plugin->GetSamplerType() == PROFILER_USER_MODE_SAMPLER) |
|
511 { |
|
512 LOGTEXT(_L(" CSamplerController::StopSamplerPlugins - flushing user mode sampler stream")); |
|
513 plugin->Flush(); |
|
514 } |
|
515 } |
|
516 count++; |
|
517 } |
|
518 } |
|
519 return count; |
|
520 } |
|
521 |
|
522 // end of file |
|
523 |
|
524 |
|
525 |
|
526 |
|