|
1 /* |
|
2 * Copyright (c) 2002 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 // AKNSOUNDPLAYER.CPP |
|
19 // |
|
20 // Copyright (c) 1997-2001 Symbian Ltd. All rights reserved. |
|
21 // |
|
22 |
|
23 // Avkon KeySound Player |
|
24 |
|
25 |
|
26 #include "aknsoundplayer.h" |
|
27 |
|
28 #include <e32svr.h> |
|
29 #include <f32file.h> |
|
30 #include <eikenv.h> |
|
31 #include <barsread.h> |
|
32 #include <avkon.rsg> |
|
33 #include <eikkeysound.h> |
|
34 #include <s32mem.h> |
|
35 #include "avkon.hrh" |
|
36 #include <aknSoundinfo.h> |
|
37 |
|
38 const TInt KAknResourceBufferSize = 512; |
|
39 |
|
40 |
|
41 // RAknSoundServerSession |
|
42 |
|
43 TInt RAknSoundServerSession::Connect() |
|
44 { |
|
45 iKeySoundServerExists = EFalse; |
|
46 |
|
47 // Create a session with zero message slots (since we have no asycronous calls) |
|
48 TInt ret=CreateSession(__KEYSOUND_SERVER_NAME,TVersion(KKeySoundServMajorVN,KKeySoundServMinorVN,KKeySoundServBuildVN),0); |
|
49 if ( ret == KErrNone ) |
|
50 { |
|
51 iKeySoundServerExists = ETrue; |
|
52 } |
|
53 return KErrNone; |
|
54 } |
|
55 |
|
56 TInt RAknSoundServerSession::ServerRequest(TInt aFunction,const TIpcArgs& aArgs) |
|
57 { |
|
58 TInt err = KErrServerTerminated; |
|
59 if (Handle()) |
|
60 { |
|
61 err = SendReceive(aFunction, aArgs); |
|
62 } |
|
63 |
|
64 if (err == KErrServerTerminated) |
|
65 { |
|
66 // Try to reconnect, if the keysound server has been shutdown |
|
67 Connect(); |
|
68 if ( iKeySoundServerExists ) |
|
69 { |
|
70 err = SendReceive(aFunction, aArgs); |
|
71 } |
|
72 else |
|
73 { |
|
74 return KErrNone; // We couldn't start KeySoundServer, just omit the error.. |
|
75 } |
|
76 } |
|
77 return err; |
|
78 } |
|
79 |
|
80 TBool RAknSoundServerSession::Init(TInt aUid) |
|
81 { |
|
82 // Initialise returnCode to ETrue because ServerRequest may fail to set it if sound |
|
83 // server is broken, and in that case we do not want to attempt to load sounds from |
|
84 // resource, which may happen if the uninitialised value == EFalse. |
|
85 TPckgBuf<TInt> returnCode(ETrue); |
|
86 |
|
87 TIpcArgs args ( &returnCode, aUid ); |
|
88 ServerRequest(EKeySoundServerInit,args); |
|
89 return returnCode(); |
|
90 } |
|
91 |
|
92 #pragma warning( disable : 4244 ) |
|
93 //\S60\AVKON\SRC\Aknsoundplayer.cpp(404) : warning C4244: '=' : conversion from 'int' to 'short', possible loss of data |
|
94 |
|
95 void RAknSoundServerSession::AddSoundInfoResourceL(TInt aUid, TResourceReader aReader) |
|
96 { |
|
97 // Read information from resource read, and package up as a buffer |
|
98 CBufFlat* buffer = CBufFlat::NewL(KAknResourceBufferSize); |
|
99 CleanupStack::PushL(buffer); |
|
100 |
|
101 RBufWriteStream bufStream; |
|
102 bufStream.Open(*buffer); |
|
103 |
|
104 CleanupClosePushL(bufStream); |
|
105 |
|
106 TInt count = aReader.ReadInt16(); |
|
107 |
|
108 bufStream.WriteUint16L(count); |
|
109 |
|
110 for (TInt ii=0; ii<count; ii++) |
|
111 { |
|
112 TInt struct_id1 = aReader.ReadInt16(); |
|
113 TInt struct_id2 = aReader.ReadInt16(); |
|
114 TInt sid; |
|
115 TInt priority; |
|
116 TBool isAverell1Structure = ETrue; |
|
117 if (struct_id1 == 0x1234 && struct_id2 == 0x5678) |
|
118 { |
|
119 isAverell1Structure = EFalse; |
|
120 sid = aReader.ReadInt16(); |
|
121 priority = aReader.ReadInt16(); |
|
122 } |
|
123 else |
|
124 { |
|
125 sid = struct_id1; |
|
126 priority = struct_id2; |
|
127 } |
|
128 |
|
129 TInt soundId = (aUid << 16) + sid; |
|
130 TInt preference = aReader.ReadInt32(); |
|
131 TPtrC file = aReader.ReadTPtrC(); |
|
132 TInt frequency = aReader.ReadInt16(); |
|
133 TInt ms = aReader.ReadInt32(); |
|
134 |
|
135 TInt seqLength = aReader.ReadInt16(); |
|
136 |
|
137 bufStream.WriteUint32L(soundId); |
|
138 bufStream.WriteUint16L(priority); |
|
139 bufStream.WriteUint32L(preference); |
|
140 if (file.Length() != 0) |
|
141 { |
|
142 bufStream.WriteUint8L(0); // type 0, file |
|
143 bufStream << file; |
|
144 } |
|
145 else if (seqLength == 0) |
|
146 { |
|
147 bufStream.WriteUint8L(1); // type 1, tone |
|
148 bufStream.WriteUint16L(frequency); |
|
149 bufStream.WriteUint32L(ms); |
|
150 } |
|
151 else |
|
152 { |
|
153 // Write sequence |
|
154 bufStream.WriteUint8L(2); // type 2, sequence |
|
155 TInt actualLength = aReader.ReadUint16(); |
|
156 bufStream.WriteUint16L(actualLength); |
|
157 for (TInt count=0; count<actualLength; count++) |
|
158 { |
|
159 bufStream.WriteUint8L(aReader.ReadUint8()); |
|
160 } |
|
161 } |
|
162 if ( !seqLength && !isAverell1Structure ) |
|
163 { |
|
164 aReader.ReadUint16(); // ignore |
|
165 } |
|
166 |
|
167 bufStream.WriteUint8L(aReader.ReadUint8()); // Read volume info. |
|
168 |
|
169 } |
|
170 |
|
171 CleanupStack::PopAndDestroy(); // bufstream close |
|
172 |
|
173 TPtr8 bufPtr = buffer->Ptr(0); |
|
174 TIpcArgs args (aUid, bufPtr.Length(), &bufPtr); |
|
175 User::LeaveIfError( ServerRequest(EKeySoundServerAddSIDS,args) ); |
|
176 |
|
177 CleanupStack::PopAndDestroy(); // buffer |
|
178 } |
|
179 |
|
180 |
|
181 void RAknSoundServerSession::PushContextL(TInt aUid, TResourceReader& aReader, TInt aResourceId) |
|
182 { |
|
183 |
|
184 TInt items = aReader.ReadInt16(); |
|
185 TInt resSize = (items * 5); |
|
186 |
|
187 CBufFlat* buffer = CBufFlat::NewL(resSize); |
|
188 CleanupStack::PushL(buffer); |
|
189 |
|
190 RBufWriteStream bufStream; |
|
191 bufStream.Open(*buffer); |
|
192 |
|
193 CleanupClosePushL(bufStream); |
|
194 |
|
195 for (TInt ii=0; ii<items; ii++) |
|
196 { |
|
197 TInt sid = aReader.ReadInt16(); |
|
198 TInt key = aReader.ReadUint16(); |
|
199 TInt type = aReader.ReadInt8(); |
|
200 bufStream.WriteInt16L(sid); |
|
201 bufStream.WriteUint16L(key); |
|
202 bufStream.WriteUint8L(type); |
|
203 } |
|
204 |
|
205 CleanupStack::PopAndDestroy(); // bufstream close |
|
206 |
|
207 |
|
208 TPtr8 bufPtr = buffer->Ptr(0); |
|
209 TIpcArgs args (items, &bufPtr, aUid, aResourceId); |
|
210 User::LeaveIfError(ServerRequest(EKeySoundServerPushContext,args)); |
|
211 CleanupStack::PopAndDestroy(); // buffer |
|
212 } |
|
213 |
|
214 void RAknSoundServerSession::PopContext() |
|
215 { |
|
216 ServerRequest(EKeySoundServerPopContext,TIpcArgs()); |
|
217 } |
|
218 |
|
219 void RAknSoundServerSession::PlaySound(TInt aSid) |
|
220 { |
|
221 ServerRequest(EKeySoundServerPlaySID,TIpcArgs(aSid)); |
|
222 } |
|
223 |
|
224 void RAknSoundServerSession::StopSound(TInt aSid) |
|
225 { |
|
226 ServerRequest(EKeySoundServerStopCurrentTone,TIpcArgs(aSid)); |
|
227 } |
|
228 |
|
229 void RAknSoundServerSession::KeyPressed(TInt aKey, TBool aRepeat) |
|
230 { |
|
231 TIpcArgs args (aKey,aRepeat); |
|
232 ServerRequest(EKeySoundServerPlayKey,args); |
|
233 } |
|
234 |
|
235 |
|
236 void RAknSoundServerSession::BringToForeground() |
|
237 { |
|
238 ServerRequest(EKeySoundServerBringToForeground,TIpcArgs()); |
|
239 } |
|
240 |
|
241 void RAknSoundServerSession::LockContext() |
|
242 { |
|
243 ServerRequest(EKeySoundServerLockContext,TIpcArgs()); |
|
244 } |
|
245 |
|
246 void RAknSoundServerSession::ReleaseContext() |
|
247 { |
|
248 ServerRequest(EKeySoundServerReleaseContext,TIpcArgs()); |
|
249 } |
|
250 |
|
251 TInt RAknSoundServerSession::TopContext() |
|
252 { |
|
253 TInt aContextResourceId = 0; |
|
254 TPckg<TInt> pckg(aContextResourceId); |
|
255 ServerRequest(EKeySoundServerTopContext,TIpcArgs(&pckg)); |
|
256 return aContextResourceId; |
|
257 } |
|
258 |
|
259 |
|
260 void RAknSoundServerSession::DisableNextKeySound( TInt aScanCode ) |
|
261 { |
|
262 ServerRequest( EKeySoundServerDisableNextKeySound, TIpcArgs( aScanCode ) ); |
|
263 } |
|
264 |
|
265 |
|
266 |
|
267 // CAknSoundPlayer |
|
268 |
|
269 CAknSoundPlayer* CAknSoundPlayer::NewL(TInt aUid) |
|
270 { |
|
271 CAknSoundPlayer* self = new(ELeave)CAknSoundPlayer(aUid); |
|
272 return self; |
|
273 } |
|
274 |
|
275 CAknSoundPlayer::CAknSoundPlayer(TInt aUid) |
|
276 :iAppUid(aUid) |
|
277 { |
|
278 } |
|
279 |
|
280 |
|
281 CAknSoundPlayer::~CAknSoundPlayer() |
|
282 { |
|
283 iSession.Close(); |
|
284 } |
|
285 |
|
286 |
|
287 |
|
288 void CAknSoundPlayer::ConstructL() |
|
289 { |
|
290 User::LeaveIfError(iSession.Connect()); |
|
291 TInt init = iSession.Init(iAppUid); |
|
292 if (init == EFalse) |
|
293 { |
|
294 // Add the default system sounds if the system has not yet been initialized |
|
295 DoAddSoundInfoResourceL(0, R_AVKON_DEFAULT_SOUND_LIST); |
|
296 // Push default skey context |
|
297 DoPushContextL(0, R_AVKON_DEFAULT_SKEY_LIST); |
|
298 } |
|
299 } |
|
300 |
|
301 |
|
302 void CAknSoundPlayer::DoAddSoundInfoResourceL(TInt aUid, TInt aResourceId) |
|
303 { |
|
304 TResourceReader reader; |
|
305 CEikonEnv* eikonEnv = CEikonEnv::Static(); |
|
306 eikonEnv->CreateResourceReaderLC(reader, aResourceId); |
|
307 iSession.AddSoundInfoResourceL(aUid, reader); |
|
308 CleanupStack::PopAndDestroy(); // reader |
|
309 } |
|
310 |
|
311 |
|
312 void CAknSoundPlayer::Play(TInt aSid) |
|
313 { |
|
314 // If sId is less than EAvkonSIDNoSound, than this is a app-specific |
|
315 // sound, so add the app Uid to the value so that the server can distinguish |
|
316 TInt soundId = aSid; |
|
317 if (soundId < EAvkonSIDNoSound) |
|
318 { |
|
319 soundId = (iAppUid << 16) + aSid; |
|
320 }; |
|
321 iSession.PlaySound(soundId); |
|
322 } |
|
323 |
|
324 void CAknSoundPlayer::Stop(TInt aSid) |
|
325 { |
|
326 // If sId is less than EAvkonSIDNoSound, than this is a app-specific |
|
327 // sound, so add the app Uid to the value so that the server can distinguish |
|
328 TInt soundId = aSid; |
|
329 if (soundId < EAvkonSIDNoSound) |
|
330 { |
|
331 soundId = (iAppUid << 16) + aSid; |
|
332 }; |
|
333 iSession.StopSound(soundId); |
|
334 } |
|
335 |
|
336 void CAknSoundPlayer::PlaySound(TInt aScanCode, TInt aRepeat) |
|
337 { |
|
338 iSession.KeyPressed(aScanCode, aRepeat); |
|
339 } |
|
340 |
|
341 |
|
342 |
|
343 void CAknSoundPlayer::AddAppSoundInfoListL(TInt aResourceId) |
|
344 { |
|
345 TResourceReader reader; |
|
346 CEikonEnv* eikonEnv = CEikonEnv::Static(); |
|
347 eikonEnv->CreateResourceReaderLC(reader, aResourceId); |
|
348 iSession.AddSoundInfoResourceL(iAppUid, reader); |
|
349 CleanupStack::PopAndDestroy(); // reader |
|
350 } |
|
351 |
|
352 |
|
353 void CAknSoundPlayer::PushContextL(TInt aResource) |
|
354 { |
|
355 DoPushContextL(iAppUid, aResource); |
|
356 } |
|
357 |
|
358 void CAknSoundPlayer::DoPushContextL(TInt aUid, TInt aResource) |
|
359 { |
|
360 TResourceReader reader; |
|
361 CEikonEnv* eikonEnv = CEikonEnv::Static(); |
|
362 eikonEnv->CreateResourceReaderLC(reader, aResource); |
|
363 iSession.PushContextL(aUid, reader, aResource); |
|
364 CleanupStack::PopAndDestroy(); // reader |
|
365 } |
|
366 |
|
367 void CAknSoundPlayer::PopContext() |
|
368 { |
|
369 iSession.PopContext(); |
|
370 } |
|
371 |
|
372 void CAknSoundPlayer::BringToForeground() |
|
373 { |
|
374 iSession.BringToForeground(); |
|
375 } |
|
376 |
|
377 void CAknSoundPlayer::LockContext() |
|
378 { |
|
379 iSession.LockContext(); |
|
380 } |
|
381 |
|
382 void CAknSoundPlayer::ReleaseContext() |
|
383 { |
|
384 iSession.ReleaseContext(); |
|
385 } |
|
386 |
|
387 TInt CAknSoundPlayer::TopContext() |
|
388 { |
|
389 return iSession.TopContext(); |
|
390 } |
|
391 |
|
392 void CAknSoundPlayer::DisableNextKeySound( TInt aScanCode ) |
|
393 { |
|
394 return iSession.DisableNextKeySound( aScanCode ); |
|
395 } |
|
396 |
|
397 |
|
398 TInt CAknSoundPlayer::RequestSoundInfoL(TInt aAvkonSid, CAknSoundInfo& aInfo) |
|
399 { |
|
400 TInt ret = KErrNotFound; |
|
401 TResourceReader reader; |
|
402 CEikonEnv::Static()->CreateResourceReaderLC(reader, R_AVKON_DEFAULT_SOUND_LIST); |
|
403 TInt count = reader.ReadInt16(); |
|
404 |
|
405 for (TInt i = 0; i < count; i++) |
|
406 { |
|
407 TInt sid; |
|
408 TInt struct_id1 = reader.ReadInt16(); |
|
409 TInt struct_id2 = reader.ReadInt16(); |
|
410 TBool isAverell1Structure = ETrue; |
|
411 if (struct_id1 == 0x1234 && struct_id2 == 0x5678) |
|
412 { |
|
413 isAverell1Structure = EFalse; |
|
414 sid = reader.ReadInt16(); |
|
415 aInfo.iPriority = (TInt16)reader.ReadInt16(); |
|
416 } |
|
417 else |
|
418 { |
|
419 sid = struct_id1; |
|
420 aInfo.iPriority = struct_id2; |
|
421 } |
|
422 |
|
423 aInfo.iPreference = reader.ReadInt32(); |
|
424 TPtrC file = reader.ReadTPtrC(); |
|
425 aInfo.iFrequency = (TInt16)reader.ReadInt16(); |
|
426 aInfo.iDuration = reader.ReadInt32(); |
|
427 |
|
428 TInt seqLength = reader.ReadInt16(); |
|
429 |
|
430 if (file.Length() != 0) |
|
431 { |
|
432 aInfo.iType = ESoundFile; |
|
433 delete aInfo.iFile; |
|
434 aInfo.iFile = 0; |
|
435 aInfo.iFile = file.AllocL(); |
|
436 } |
|
437 else if (seqLength == 0) |
|
438 { |
|
439 aInfo.iType = ESoundTone; |
|
440 } |
|
441 else |
|
442 { |
|
443 // type 2, sequence |
|
444 aInfo.iType = ESoundSequence; |
|
445 delete aInfo.iSequence; |
|
446 aInfo.iSequence = 0; |
|
447 TInt length = reader.ReadInt16(); |
|
448 aInfo.iSequence = HBufC8::NewMaxL(length); |
|
449 TPtr8 ptr = aInfo.iSequence->Des(); |
|
450 for (TInt ii = 0; ii < length; ii++) |
|
451 { |
|
452 ptr[ii] = reader.ReadUint8(); |
|
453 } |
|
454 } |
|
455 |
|
456 if ( !seqLength && !isAverell1Structure ) |
|
457 { |
|
458 reader.ReadInt16(); |
|
459 } |
|
460 |
|
461 aInfo.iVolume = (TUint8)reader.ReadUint8(); |
|
462 |
|
463 if ( sid == aAvkonSid ) |
|
464 { |
|
465 ret = KErrNone; |
|
466 break; |
|
467 } |
|
468 } |
|
469 |
|
470 CleanupStack::PopAndDestroy(); // reader |
|
471 return ret; |
|
472 } |
|
473 |
|
474 #pragma warning( default : 4244 ) |
|
475 |
|
476 |
|
477 // End of File |