|
1 //mmfaudioserver.cpp |
|
2 |
|
3 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 // All rights reserved. |
|
5 // This component and the accompanying materials are made available |
|
6 // under the terms of "Eclipse Public License v1.0" |
|
7 // which accompanies this distribution, and is available |
|
8 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
9 // |
|
10 // Initial Contributors: |
|
11 // Nokia Corporation - initial contribution. |
|
12 // |
|
13 // Contributors: |
|
14 // |
|
15 // Description: |
|
16 // Portions Copyright Nokia-Symbian * Nokia Core OS * |
|
17 // INCLUDE FILES |
|
18 // |
|
19 |
|
20 #include <e32math.h> |
|
21 #include <mmf/common/mmfbase.hrh> |
|
22 |
|
23 #include "mmfaudioserver.h" |
|
24 #include "mmfaudioserverdecs.h" |
|
25 #include "mmfdevsoundsession.h" |
|
26 #include "mmfaudioserversession.h" |
|
27 #include "mmfdevsoundserver.h" |
|
28 #include "mmfdevsoundserverstart.h" |
|
29 #include "mmfaudioserverfactory.h" |
|
30 #include "devsoundsvrthreadpriorityconsts.h" |
|
31 |
|
32 #ifdef _DEBUG |
|
33 #include "e32debug.h" |
|
34 #define SYMBIAN_DEBPRN0(str) RDebug::Print(str, this) |
|
35 #else |
|
36 #define SYMBIAN_DEBPRN0(str) |
|
37 #endif //_DEBUG |
|
38 |
|
39 |
|
40 // Time delay that the audio server wait before shutdown itself when is detected that the last DevSoundSession is closed |
|
41 const TInt KAudioServerShutDownDelay = 50000000; //50 sec |
|
42 |
|
43 // ======== LOCAL FUNCTIONS ======== |
|
44 |
|
45 void Panic(TInt aPanicCode) |
|
46 { |
|
47 _LIT(KAudioServerPanicCategory, "mmfaudioserver"); |
|
48 User::Panic(KAudioServerPanicCategory, aPanicCode); |
|
49 } |
|
50 |
|
51 // ============================ MEMBER FUNCTIONS =============================== |
|
52 |
|
53 // ----------------------------------------------------------------------------- |
|
54 // CMMFAudioServer::NewL |
|
55 // Two-phased constructor. |
|
56 // ----------------------------------------------------------------------------- |
|
57 // |
|
58 CMMFAudioServer* CMMFAudioServer::NewL() |
|
59 { |
|
60 CMMFAudioServer* self = new(ELeave) CMMFAudioServer(); |
|
61 CleanupStack::PushL(self); |
|
62 self->ConstructL(); |
|
63 CleanupStack::Pop(self); |
|
64 return self; |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CMMFAudioServer::CMMFAudioServer |
|
69 // C++ default constructor can NOT contain any code, that |
|
70 // might leave. |
|
71 // ----------------------------------------------------------------------------- |
|
72 // |
|
73 CMMFAudioServer::CMMFAudioServer() |
|
74 : CMmfIpcServer(EPriorityStandard) |
|
75 { |
|
76 } |
|
77 |
|
78 // ----------------------------------------------------------------------------- |
|
79 // CMMFAudioServer::ConstructL |
|
80 // Symbian 2nd phase constructor can leave. |
|
81 // ----------------------------------------------------------------------------- |
|
82 // |
|
83 void CMMFAudioServer::ConstructL() |
|
84 { |
|
85 SYMBIAN_DEBPRN0(_L("CMMFAudioServer[0x%x]::ConstructL - enter")); |
|
86 |
|
87 SetPinClientDescriptors(ETrue); |
|
88 // Call base class to Start server |
|
89 StartL(KAudioServerName); |
|
90 |
|
91 iFourCCConvertor = CFourCCConvertor::NewL(); |
|
92 iDelayAudioServerShutDown = CDelayAudioServerShutDown::NewL(); |
|
93 |
|
94 iFactory = CMMFAudioServerFactory::NewL(); |
|
95 iFactory->StartL(*this); |
|
96 |
|
97 SYMBIAN_DEBPRN0(_L("CMMFAudioServer[0x%x]::ConstructL - exit")); |
|
98 } |
|
99 |
|
100 // ----------------------------------------------------------------------------- |
|
101 // CMMFAudioServer::~CMMFAudioServer |
|
102 // Destructor |
|
103 // ----------------------------------------------------------------------------- |
|
104 // |
|
105 CMMFAudioServer::~CMMFAudioServer() |
|
106 { |
|
107 if (iDelayAudioServerShutDown) |
|
108 { |
|
109 iDelayAudioServerShutDown->Cancel(); |
|
110 delete iDelayAudioServerShutDown; |
|
111 iDelayAudioServerShutDown = NULL; |
|
112 } |
|
113 |
|
114 for(TInt i=(iDevSoundServList.Count()-1); i >=0 ; i--) |
|
115 { |
|
116 CStartAndMonitorDevSoundThread* devSoundMonitorThread = iDevSoundServList[i]; |
|
117 iDevSoundServList.Remove(i); |
|
118 delete devSoundMonitorThread; |
|
119 } |
|
120 iDevSoundServList.Close(); |
|
121 delete iFourCCConvertor; |
|
122 if (iFactory) |
|
123 { |
|
124 iFactory->Stop(*this); |
|
125 delete iFactory; |
|
126 } |
|
127 } |
|
128 |
|
129 // ----------------------------------------------------------------------------- |
|
130 // CMMFAudioServer::NewSessionL |
|
131 // Creates a new session to handle requests by the client and returns it to the |
|
132 // client server framework. |
|
133 // ----------------------------------------------------------------------------- |
|
134 // |
|
135 CMmfIpcSession* CMMFAudioServer::NewSessionL(const TVersion& aVersion) const |
|
136 { |
|
137 SYMBIAN_DEBPRN0(_L("CMMFAudioServer[0x%x]::NewSessionL - enter")); |
|
138 |
|
139 TVersion v(KMMFAudioServerVersion, |
|
140 KMMFAudioServerMinorVersionNumber, |
|
141 KMMFAudioServerBuildVersionNumber); |
|
142 if(!User::QueryVersionSupported(v, aVersion)) |
|
143 { |
|
144 User::Leave(KErrNotSupported); |
|
145 } |
|
146 |
|
147 for(TInt i=(iDevSoundServList.Count()-1); i >=0 ; i--) |
|
148 { |
|
149 CStartAndMonitorDevSoundThread* devSoundMonitorThread = iDevSoundServList[i]; |
|
150 |
|
151 if(!devSoundMonitorThread->IsActive()) |
|
152 { |
|
153 iDevSoundServList.Remove(i); |
|
154 delete devSoundMonitorThread; |
|
155 } |
|
156 iDevSoundServList.Compress(); |
|
157 } |
|
158 |
|
159 RMMFDevSoundServerProxy devSoundSessionHandle; |
|
160 User::LeaveIfError(StartDevSoundServer(devSoundSessionHandle)); |
|
161 CMMFAudioServerSession* audioServerSession = CMMFAudioServerSession::NewL(devSoundSessionHandle); |
|
162 SYMBIAN_DEBPRN0(_L("CMMFAudioServer[0x%x]::NewSessionL - session created")); |
|
163 return audioServerSession; |
|
164 } |
|
165 |
|
166 // ----------------------------------------------------------------------------- |
|
167 // CMMFAudioServer::IncrementSessionId |
|
168 // Increment the session Id. |
|
169 // ----------------------------------------------------------------------------- |
|
170 // |
|
171 void CMMFAudioServer::IncrementSessionId() |
|
172 { |
|
173 iAudioServerSessionId++; |
|
174 } |
|
175 |
|
176 // ----------------------------------------------------------------------------- |
|
177 // CMMFAudioServer::DecrementSessionId |
|
178 // Decrement the session Id. |
|
179 // ----------------------------------------------------------------------------- |
|
180 // |
|
181 void CMMFAudioServer::DecrementSessionId() |
|
182 { |
|
183 iAudioServerSessionId--; |
|
184 } |
|
185 |
|
186 // ----------------------------------------------------------------------------- |
|
187 // CMMFAudioServer::IncrementDevSoundCount |
|
188 // Increment the DevSound server counter. If there is atleast one DevSound |
|
189 // server, it will cancel its shutdown timer. |
|
190 // ----------------------------------------------------------------------------- |
|
191 // |
|
192 void CMMFAudioServer::IncrementDevSoundCount() |
|
193 { |
|
194 iDevSoundCount++; |
|
195 //in the case we started the shutdown due to no more DevSound |
|
196 if(iDevSoundCount) |
|
197 { |
|
198 ASSERT(iDelayAudioServerShutDown); |
|
199 if (iDelayAudioServerShutDown) |
|
200 { |
|
201 iDelayAudioServerShutDown->Cancel(); |
|
202 } |
|
203 } |
|
204 } |
|
205 |
|
206 // ----------------------------------------------------------------------------- |
|
207 // CMMFAudioServer::DecrementDevSoundCount |
|
208 // Decrement the DevSound server counter. Once the number of DevSound server's |
|
209 // instances becomes zero, Audio Server will start its shutdown routine. |
|
210 // ----------------------------------------------------------------------------- |
|
211 // |
|
212 void CMMFAudioServer::DecrementDevSoundCount() |
|
213 { |
|
214 iDevSoundCount--; |
|
215 if (iDevSoundCount == 0) |
|
216 { |
|
217 ASSERT(iDelayAudioServerShutDown); |
|
218 if (iDelayAudioServerShutDown) |
|
219 { |
|
220 iDelayAudioServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(KAudioServerShutDownDelay)); |
|
221 } |
|
222 } |
|
223 } |
|
224 |
|
225 // ----------------------------------------------------------------------------- |
|
226 // CMMFAudioServer::SendEventToClient |
|
227 // Sends Event to DevSound client. |
|
228 // ----------------------------------------------------------------------------- |
|
229 // |
|
230 void CMMFAudioServer::SendEventToClient(TInt aSessionToAlert, TInt /*aSessionToBeLaunched*/) |
|
231 { |
|
232 // For the session requested, send event to client |
|
233 iSessionIter.SetToFirst(); |
|
234 CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++); |
|
235 while (session) |
|
236 { |
|
237 if (session->AudioServerSessionId() == aSessionToAlert) |
|
238 { |
|
239 break; // Finished |
|
240 } |
|
241 |
|
242 session = static_cast<CMMFAudioServerSession*>(iSessionIter++); |
|
243 } |
|
244 } |
|
245 |
|
246 // ----------------------------------------------------------------------------- |
|
247 // CMMFAudioServer::LaunchRequest |
|
248 // Launches the DevSound servers waiting for Audio Policy. |
|
249 // ----------------------------------------------------------------------------- |
|
250 // |
|
251 void CMMFAudioServer::LaunchRequest(TInt aSessionId) |
|
252 { |
|
253 iSessionIter.SetToFirst(); |
|
254 CMMFAudioServerSession* session = static_cast<CMMFAudioServerSession*>(iSessionIter++); |
|
255 |
|
256 while (session) |
|
257 { |
|
258 if (session->AudioServerSessionId() == aSessionId) |
|
259 { |
|
260 break; // Finished |
|
261 } |
|
262 session = static_cast<CMMFAudioServerSession*>(iSessionIter++); |
|
263 } |
|
264 } |
|
265 |
|
266 // ----------------------------------------------------------------------------- |
|
267 // CMMFAudioServer::StartDevSoundServer |
|
268 // Starts a new DevSound server instance. |
|
269 // ----------------------------------------------------------------------------- |
|
270 // |
|
271 TInt CMMFAudioServer::StartDevSoundServer(RMMFDevSoundServerProxy& aDevSoundSessionHandle) const |
|
272 { |
|
273 SYMBIAN_DEBPRN0(_L("CMMFAudioServer[0x%x]::StartDevSoundServer - enter")); |
|
274 |
|
275 RMessage2 message(Message()); |
|
276 CStartAndMonitorDevSoundThread* monitorDevSound = NULL; |
|
277 |
|
278 TRAPD(err, monitorDevSound = CStartAndMonitorDevSoundThread::NewL(const_cast<CMMFAudioServer*>(this))); |
|
279 if(err != KErrNone) |
|
280 { |
|
281 delete monitorDevSound; |
|
282 return err; |
|
283 } |
|
284 |
|
285 err = iDevSoundServList.Append(monitorDevSound); |
|
286 if(err != KErrNone) |
|
287 { |
|
288 delete monitorDevSound; |
|
289 return err; |
|
290 } |
|
291 |
|
292 SYMBIAN_DEBPRN0(_L("CMMFAudioServer[0x%x]::StartDevSoundServer - exit")); |
|
293 return monitorDevSound->StartDevSoundServer(message, aDevSoundSessionHandle); |
|
294 |
|
295 } |
|
296 |
|
297 // ----------------------------------------------------------------------------- |
|
298 // CMMFAudioServer::CDelayAudioServerShutDown::NewL |
|
299 // Two-phased constructor. |
|
300 // ----------------------------------------------------------------------------- |
|
301 // |
|
302 CMMFAudioServer::CDelayAudioServerShutDown* |
|
303 CMMFAudioServer::CDelayAudioServerShutDown::NewL() |
|
304 { |
|
305 CDelayAudioServerShutDown* self = new(ELeave) CDelayAudioServerShutDown; |
|
306 CleanupStack::PushL(self); |
|
307 self->ConstructL(); |
|
308 CleanupStack::Pop(self); |
|
309 return self; |
|
310 } |
|
311 |
|
312 // ----------------------------------------------------------------------------- |
|
313 // Constructor. |
|
314 // ----------------------------------------------------------------------------- |
|
315 // |
|
316 CMMFAudioServer::CDelayAudioServerShutDown::CDelayAudioServerShutDown() |
|
317 : CActive(0) |
|
318 { |
|
319 } |
|
320 |
|
321 // ----------------------------------------------------------------------------- |
|
322 // CMMFAudioServer::CDelayAudioServerShutDown::ConstructL |
|
323 // ----------------------------------------------------------------------------- |
|
324 // |
|
325 void CMMFAudioServer::CDelayAudioServerShutDown::ConstructL() |
|
326 { |
|
327 User::LeaveIfError(iShutDownTimer.CreateLocal()); |
|
328 CActiveScheduler::Add(this); |
|
329 } |
|
330 |
|
331 // ----------------------------------------------------------------------------- |
|
332 // CMMFAudioServer::CDelayAudioServerShutDown::~CDelayAudioServerShutDown |
|
333 // ----------------------------------------------------------------------------- |
|
334 // |
|
335 CMMFAudioServer::CDelayAudioServerShutDown::~CDelayAudioServerShutDown() |
|
336 { |
|
337 Cancel(); |
|
338 iShutDownTimer.Close(); |
|
339 } |
|
340 |
|
341 // ----------------------------------------------------------------------------- |
|
342 // CMMFAudioServer::CDelayAudioServerShutDown::SetDelay |
|
343 // Request a timeout after aDelay |
|
344 // ----------------------------------------------------------------------------- |
|
345 // |
|
346 void CMMFAudioServer::CDelayAudioServerShutDown::SetDelay( |
|
347 TTimeIntervalMicroSeconds32 aDelay) |
|
348 { |
|
349 __ASSERT_ALWAYS(!IsActive(), Panic(EMMFAudioServerIsActive)); |
|
350 iShutDownTimer.After(iStatus, aDelay); |
|
351 SetActive(); |
|
352 } |
|
353 |
|
354 // ----------------------------------------------------------------------------- |
|
355 // CMMFAudioServer::CDelayAudioServerShutDown::RunL |
|
356 // Called by Active object framework when timer times out. |
|
357 // ----------------------------------------------------------------------------- |
|
358 // |
|
359 void CMMFAudioServer::CDelayAudioServerShutDown::RunL() |
|
360 { |
|
361 CActiveScheduler::Stop(); |
|
362 } |
|
363 |
|
364 // ----------------------------------------------------------------------------- |
|
365 // CMMFAudioServer::CDelayAudioServerShutDown::DoCancel |
|
366 // Called by the Active object framework when user cancels active object. |
|
367 // ----------------------------------------------------------------------------- |
|
368 // |
|
369 void CMMFAudioServer::CDelayAudioServerShutDown::DoCancel() |
|
370 { |
|
371 iShutDownTimer.Cancel(); |
|
372 } |
|
373 |
|
374 // ----------------------------------------------------------------------------- |
|
375 // CStartAndMonitorDevSoundThread::NewL |
|
376 // ----------------------------------------------------------------------------- |
|
377 // |
|
378 CStartAndMonitorDevSoundThread* CStartAndMonitorDevSoundThread::NewL( |
|
379 CMMFAudioServer* aAudioServer) |
|
380 { |
|
381 CStartAndMonitorDevSoundThread* self = new(ELeave) CStartAndMonitorDevSoundThread(aAudioServer); |
|
382 CleanupStack::PushL(self); |
|
383 self->ConstructL(); |
|
384 CleanupStack::Pop(self); |
|
385 return self; |
|
386 } |
|
387 |
|
388 // ----------------------------------------------------------------------------- |
|
389 // CStartAndMonitorDevSoundThread::ConstructL |
|
390 // ----------------------------------------------------------------------------- |
|
391 // |
|
392 void CStartAndMonitorDevSoundThread::ConstructL() |
|
393 { |
|
394 CActiveScheduler::Add(this); |
|
395 } |
|
396 |
|
397 // ----------------------------------------------------------------------------- |
|
398 // CStartAndMonitorDevSoundThread::StartDevSoundServer |
|
399 // Starts a new DevSound server. |
|
400 // ----------------------------------------------------------------------------- |
|
401 // |
|
402 TInt CStartAndMonitorDevSoundThread::StartDevSoundServer( |
|
403 RMessage2& aMessage, |
|
404 RMMFDevSoundServerProxy& aDevSoundSessionHandle) |
|
405 { |
|
406 SYMBIAN_DEBPRN0(_L("CStartAndMonitorDevSoundThread[0x%x]::StartDevSoundServer - enter")); |
|
407 |
|
408 RThread clientThread; |
|
409 TInt err(KErrNone); |
|
410 |
|
411 // Open handle to client thread |
|
412 err = aMessage.Client(clientThread); |
|
413 if (err != KErrNone) |
|
414 { |
|
415 clientThread.Close(); |
|
416 return err; |
|
417 } |
|
418 // Open a process-relative handle to the process which owns clientThread. |
|
419 RProcess clientProcess; |
|
420 err = clientThread.Process(clientProcess); |
|
421 |
|
422 if (err != KErrNone) |
|
423 { |
|
424 // Close client thread handle and return error |
|
425 clientThread.Close(); |
|
426 return err; |
|
427 } |
|
428 |
|
429 // Get the client process id |
|
430 TProcessId clientProcessId(clientProcess.Id()); |
|
431 |
|
432 // Close client thread and client process handles |
|
433 clientThread.Close(); |
|
434 clientProcess.Close(); |
|
435 |
|
436 RServer2 devSoundServerHandle; |
|
437 devSoundServerHandle.SetReturnedHandle(0); |
|
438 |
|
439 //Pass to DevSoundServer the clien't process ID |
|
440 TDevSoundServerStart start(iAudioServer, |
|
441 clientProcessId, |
|
442 devSoundServerHandle); |
|
443 |
|
444 TThreadFunction serverFunc=CMMFDevSoundServer::StartThread; |
|
445 |
|
446 // To deal with the unique thread (+semaphore!) naming in EPOC, |
|
447 // and that we may be trying to restart a server that has just |
|
448 // exited we attempt to create a unique thread name for the server. |
|
449 #ifdef SYMBIAN_USE_SEPARATE_HEAPS |
|
450 err = iServer.Create(KNullDesC,serverFunc,KDevSoundServerStackSize*2, |
|
451 KDevSoundServerInitHeapSize, |
|
452 KDevSoundServerMaxHeapSize, |
|
453 &start, |
|
454 EOwnerProcess); |
|
455 #else |
|
456 err = iServer.Create(KNullDesC, |
|
457 serverFunc, |
|
458 (KDevSoundServerStackSize*2), |
|
459 NULL, |
|
460 &start, |
|
461 EOwnerProcess); |
|
462 #endif // SYMBIAN_USE_SEPARATE_HEAPS |
|
463 if(err != KErrNone) |
|
464 { |
|
465 return err; |
|
466 } |
|
467 iServer.SetPriority(KDevsoundSvrPriority); |
|
468 |
|
469 // Synchronise with the server |
|
470 TRequestStatus reqStatus; |
|
471 iServer.Rendezvous(reqStatus); |
|
472 |
|
473 if (reqStatus!=KRequestPending) |
|
474 { |
|
475 iServer.Kill(0); |
|
476 } |
|
477 else |
|
478 { |
|
479 // Start the test harness |
|
480 iServer.Resume(); |
|
481 // Server will call the reciprocal static synchronise call |
|
482 } |
|
483 |
|
484 // note devSoundServerHandle really "owned" by client thread - just copied here |
|
485 |
|
486 User::WaitForRequest(reqStatus); // wait for start or death |
|
487 if(reqStatus.Int() != KErrNone) |
|
488 { |
|
489 // close our handle to the thread. If we reach here, the thread should have |
|
490 // closed anyway as continue Rendezvous is always KErrNone() |
|
491 iServer.Close(); |
|
492 return reqStatus.Int(); |
|
493 } |
|
494 |
|
495 err = aDevSoundSessionHandle.Open(devSoundServerHandle); |
|
496 |
|
497 if(err != KErrNone) |
|
498 { |
|
499 // close our handle to the thread. If we reach here, this means that NewSessionL() failed |
|
500 // on server, and that action itself will asynchronously stop the thread |
|
501 iServer.Close(); |
|
502 return err; |
|
503 } |
|
504 |
|
505 aDevSoundSessionHandle.ShareProtected(); |
|
506 iServer.Logon(iStatus); |
|
507 SetActive(); |
|
508 |
|
509 iAudioServer->IncrementDevSoundCount(); |
|
510 |
|
511 SYMBIAN_DEBPRN0(_L("CStartAndMonitorDevSoundThread[0x%x]::StartDevSoundServer - exit")); |
|
512 return KErrNone; |
|
513 } |
|
514 |
|
515 // ----------------------------------------------------------------------------- |
|
516 // CStartAndMonitorDevSoundThread::CStartAndMonitorDevSoundThread |
|
517 // Constructor |
|
518 // ----------------------------------------------------------------------------- |
|
519 // |
|
520 CStartAndMonitorDevSoundThread::CStartAndMonitorDevSoundThread( |
|
521 CMMFAudioServer* aAudioServer) |
|
522 : CActive(EPriorityStandard),iAudioServer(aAudioServer) |
|
523 { |
|
524 |
|
525 } |
|
526 |
|
527 // Desctructor |
|
528 CStartAndMonitorDevSoundThread::~CStartAndMonitorDevSoundThread() |
|
529 { |
|
530 Cancel(); |
|
531 } |
|
532 |
|
533 // ----------------------------------------------------------------------------- |
|
534 // CStartAndMonitorDevSoundThread::RunL |
|
535 // Called by Active Object framework when DevSound server is destroyed. |
|
536 // ----------------------------------------------------------------------------- |
|
537 // |
|
538 void CStartAndMonitorDevSoundThread::RunL() |
|
539 { |
|
540 iServer.Close(); |
|
541 iAudioServer->DecrementDevSoundCount(); |
|
542 } |
|
543 |
|
544 // ----------------------------------------------------------------------------- |
|
545 // CStartAndMonitorDevSoundThread::DoCancel |
|
546 // Called by Active Object framework when client cancels active object. |
|
547 // ----------------------------------------------------------------------------- |
|
548 // |
|
549 void CStartAndMonitorDevSoundThread::DoCancel() |
|
550 { |
|
551 iServer.LogonCancel(iStatus); |
|
552 } |
|
553 |
|
554 |
|
555 // ----------------------------------------------------------------------------- |
|
556 // RMMFDevSoundServerProxy::Open |
|
557 // Creates new audio server session for the devsound server. |
|
558 // ----------------------------------------------------------------------------- |
|
559 // |
|
560 TInt RMMFDevSoundServerProxy::Open(RServer2& aDevSoundServerHandle) |
|
561 { |
|
562 SYMBIAN_DEBPRN0(_L("RMMFDevSoundServerProxy[0x%x]::Open - enter")); |
|
563 TInt err = CreateSession(aDevSoundServerHandle, TVersion(KMMFDevSoundServerVersion, |
|
564 KMMFDevSoundServerMinorVersionNumber, |
|
565 KMMFDevSoundServerBuildVersionNumber), |
|
566 -1, EIpcSession_GlobalSharable); |
|
567 |
|
568 SYMBIAN_DEBPRN0(_L("RMMFDevSoundServerProxy[0x%x]::Open - exit")); |
|
569 return err; |
|
570 } |
|
571 |
|
572 // End of File |