|
1 /*------------------------------------------------------------------ |
|
2 - |
|
3 * Software Name : UserEmulator |
|
4 * Version : v4.2.1309 |
|
5 * |
|
6 * Copyright (c) 2009 France Telecom. All rights reserved. |
|
7 * This software is distributed under the License |
|
8 * "Eclipse Public License - v 1.0" the text of which is available |
|
9 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
10 * |
|
11 * Initial Contributors: |
|
12 * France Telecom |
|
13 * |
|
14 * Contributors: |
|
15 *------------------------------------------------------------------ |
|
16 - |
|
17 * File Name: serverCtrl.cpp |
|
18 * |
|
19 * Created: 13/08/2009 |
|
20 * Author(s): Marcell Kiss |
|
21 * |
|
22 * Description: |
|
23 * Implementation of Anim dll server side class |
|
24 *------------------------------------------------------------------ |
|
25 - |
|
26 * |
|
27 */ |
|
28 |
|
29 // System Includes |
|
30 #include <e32std.h> |
|
31 #include <e32event.h> |
|
32 #include <e32base.h> |
|
33 #include <BAUTILS.H> |
|
34 // User Includes |
|
35 #include "serverCtrl.h" |
|
36 #include "clientcommander.h" |
|
37 |
|
38 // Local constants |
|
39 _LIT8(KStartXml,"<!--?xml version='1.0' encoding='utf-16' ?>-->\n<UserEmulator>\n<action>\n<type>screenreset</type>\n</action>"); |
|
40 _LIT8(KEndXml, "\n</UserEmulator>"); |
|
41 _LIT8(KStr,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys> %d </keys>\n</action>"); |
|
42 _LIT8(KUp,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>UAK</keys>\n</action>"); |
|
43 _LIT8(KDown,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>DAK</keys>\n</action>"); |
|
44 _LIT8(KLeft,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>LAK</keys>\n</action>"); |
|
45 _LIT8(KRight,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>RAK</keys>\n</action>"); |
|
46 _LIT8(KLSK,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>LSK</keys>\n</action>"); |
|
47 _LIT8(KRSK,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>RSK</keys>\n</action>"); |
|
48 _LIT8(KMSK,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>MSK</keys>\n</action>"); |
|
49 _LIT8(KBS,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>BS</keys>\n</action>"); |
|
50 _LIT8(KAsterisk,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>*</keys>\n</action>"); |
|
51 _LIT8(KYes,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>KYES</keys>\n</action>"); |
|
52 _LIT8(KNo,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>KNO</keys>\n</action>"); |
|
53 _LIT8(KHash,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>#</keys>\n</action>"); |
|
54 _LIT8(KTasks,"\n<action>\n<name>key</name>\n<type>keypress</type>\n<params>%d</params>\n<keys>MENU</keys>\n</action>"); |
|
55 _LIT8(KScreenShot1,"\n<action>\n<name> Pause </name>\n<type> wait </type>\n<params> 10 </params>\n<screenshot>"); |
|
56 _LIT8(KScreenShot2,"-%LD</screenshot>\n</action>"); |
|
57 |
|
58 _LIT8(KPortrait,"\n<action>\n<name>Orientation</name>\n<type>orientation</type>\n<params>portrait</params>\n</action>"); |
|
59 _LIT8(KLandscape,"\n<action>\n<name>Orientation</name>\n<type>orientation</type>\n<params>landscape</params>\n</action>"); |
|
60 |
|
61 _LIT8(KStrWait,"\n<action>\n<name> Pause </name>\n<type> wait </type>\n<params> %d </params>\n</action>"); |
|
62 _LIT8(KStrPointerDown,"\n<action>\n<name>Pointer</name>\n<type>pointerevent</type>\n<params>pointerdownAt,%d,%d</params>\n</action>"); |
|
63 _LIT8(KStrDrag,"\n<action>\n<name>Pointer</name>\n<type>pointerevent</type>\n<params>moveTo,%d,%d</params>\n</action>"); |
|
64 _LIT8(KStrPointerUp,"\n<action>\n<name>Pointer</name>\n<type>pointerevent</type>\n<params>pointerupAt,%d,%d</params>\n</action>"); |
|
65 |
|
66 _LIT8(KCamera,"Camera"); |
|
67 |
|
68 const TInt KAsteriskKeyScanCode = 0x2A; |
|
69 const TInt KWriteBufferSize = 20; |
|
70 |
|
71 // ======== MEMBER FUNCTIONS ======== |
|
72 |
|
73 CServerCtrl::CServerCtrl():iMainBuffer(NULL) |
|
74 {// No implementation required |
|
75 } |
|
76 |
|
77 CServerCtrl::~CServerCtrl() |
|
78 { |
|
79 delete iCaptureKeyTimer; |
|
80 iCaptureKeyTimer = NULL; |
|
81 |
|
82 if(iMainBuffer) |
|
83 { |
|
84 // If buffer's length is not zero then write that data to file. |
|
85 if(iMainBuffer->Length()>0) |
|
86 iRFile.Write(*iMainBuffer); |
|
87 |
|
88 delete iMainBuffer; |
|
89 iMainBuffer = NULL; |
|
90 } |
|
91 |
|
92 iRFile.Close(); |
|
93 iFs.Close(); |
|
94 } |
|
95 // ---------------------------------------------------------- |
|
96 // Second phase constructor |
|
97 // ---------------------------------------------------------- |
|
98 // |
|
99 void CServerCtrl::ConstructL( TAny* /* aArgs */, TBool /* aHasFocus */ ) |
|
100 { |
|
101 // Initialisation |
|
102 iRecord = EFalse; |
|
103 iFirstDelay=EFalse; |
|
104 iCameraButtonPressed = EFalse; |
|
105 iCaptureKeyTimer = CCaptureKeyTimer::NewL(*this); |
|
106 |
|
107 |
|
108 iIsEventEnabled = EFalse; |
|
109 } |
|
110 // ------------------------------------------------------------ |
|
111 // Communication between client and server. Called by client |
|
112 // ------------------------------------------------------------ |
|
113 // |
|
114 TInt CServerCtrl::CommandReplyL( TInt aCode, TAny* aArgs ) |
|
115 { |
|
116 // Execute client command (aCode) |
|
117 switch ( aCode ) |
|
118 { |
|
119 // Start recording |
|
120 case RClientCommander::EStart: |
|
121 { |
|
122 TBuf8<KBuffer512> buf((const TUint8 *)aArgs); |
|
123 // Name and path of script file defined on Settings page |
|
124 iKeyFilePath.Copy(buf); |
|
125 |
|
126 // Cut long extension names |
|
127 TInt pos=iKeyFilePath.LocateReverse('.'); |
|
128 if( pos!=KErrNotFound ) |
|
129 { |
|
130 iKeyFilePath = iKeyFilePath.Left(pos+4); |
|
131 } |
|
132 |
|
133 // Check if device is in landscape or portrait mode |
|
134 TSize screen=iFunctions->ScreenDevice()->SizeInPixels(); |
|
135 if(screen.iWidth <= screen.iHeight) |
|
136 iOrientation = ETrue; |
|
137 else |
|
138 iOrientation = EFalse; |
|
139 |
|
140 // Create script file |
|
141 User::LeaveIfError(iFs.Connect()); |
|
142 TInt val=iRFile.Replace(iFs,iKeyFilePath,EFileShareAny|EFileWrite); |
|
143 if(val!=KErrNone) |
|
144 return 1; |
|
145 |
|
146 // Write xml header to file |
|
147 buf.Copy(KStartXml); |
|
148 |
|
149 |
|
150 // Write orientation 'action' to file |
|
151 if(iOrientation) |
|
152 buf.Append(KPortrait); |
|
153 else |
|
154 buf.Append(KLandscape); |
|
155 iRecord = ETrue; |
|
156 |
|
157 iRFile.Write(buf); |
|
158 iIsEventEnabled = EFalse; |
|
159 |
|
160 // Enable raw events |
|
161 iFunctions->GetRawEvents(ETrue); |
|
162 |
|
163 iWritePointer = 0; |
|
164 // Initialise main buffer (length of it will be allocated dynamically) |
|
165 iMainBuffer = HBufC8::NewL(1); |
|
166 |
|
167 iNoCount = 0; |
|
168 |
|
169 } |
|
170 break; |
|
171 // Start wait timing |
|
172 case RClientCommander::EStartTiming: |
|
173 { |
|
174 // Store home time at start |
|
175 TTime time; |
|
176 time.HomeTime(); |
|
177 |
|
178 iWaitTimer = time; |
|
179 } |
|
180 break; |
|
181 // Stop recording |
|
182 case RClientCommander::EStop: |
|
183 { |
|
184 // Disable raw events |
|
185 iFunctions->GetRawEvents(EFalse); |
|
186 if(iRecord) |
|
187 { |
|
188 TBuf8<KBuffer64> buf; |
|
189 // Write last wait period to buffer |
|
190 CheckTimerInsertWait(); |
|
191 |
|
192 iIsEventEnabled = EFalse; |
|
193 |
|
194 // Flush buffer |
|
195 if(iMainBuffer) |
|
196 { |
|
197 if(iMainBuffer->Length()>0) |
|
198 iRFile.Write(*iMainBuffer); |
|
199 |
|
200 delete iMainBuffer; |
|
201 iMainBuffer = NULL; |
|
202 } |
|
203 |
|
204 // End tag of xml script |
|
205 buf.Copy(KEndXml); |
|
206 iRFile.Write(buf); |
|
207 |
|
208 iRecord = EFalse; |
|
209 |
|
210 iRFile.Flush(); |
|
211 iRFile.Close(); |
|
212 iFs.Close(); |
|
213 } |
|
214 } |
|
215 break; |
|
216 // Poll the status of camera button (pressed or not) |
|
217 case RClientCommander::EPoll: |
|
218 { |
|
219 TBuf8<KBuffer256> buf((const TUint8 *)aArgs); |
|
220 |
|
221 if(buf.Length()>0) |
|
222 { |
|
223 const TUint8* a = buf.Left(0).Ptr(); |
|
224 const TUint8* b = buf.Mid(1,1).Ptr(); |
|
225 TInt length; |
|
226 if(*b!=42) // 42 = '*' |
|
227 length = (*a-48)*10+(*b-48); |
|
228 else |
|
229 length = *a-48; |
|
230 |
|
231 if(length>0 && 2+length<=buf.Length()) |
|
232 buf = buf.Mid(2,length); |
|
233 } |
|
234 // Check if camera application is still in foreground or closed already. |
|
235 if(buf.Compare(KCamera)==0 && !iFirstDelay) |
|
236 iFirstDelay = ETrue; |
|
237 else |
|
238 iFirstDelay = EFalse; |
|
239 |
|
240 if(!iFirstDelay) |
|
241 { |
|
242 if(buf.Length()>2) |
|
243 iAppName.Copy(buf); |
|
244 } |
|
245 |
|
246 if(iCameraButtonPressed) |
|
247 return 1; |
|
248 |
|
249 // Check orientation and write orientation 'action' to buffer if that changed |
|
250 TSize screen=iFunctions->ScreenDevice()->SizeInPixels(); |
|
251 if(screen.iWidth <= screen.iHeight) |
|
252 { |
|
253 if(!iOrientation) |
|
254 {// log portrait |
|
255 TBuf8<KBuffer128> buf; |
|
256 buf.Copy(KPortrait); |
|
257 WriteFile(buf); |
|
258 } |
|
259 iOrientation = ETrue; |
|
260 } |
|
261 else |
|
262 { |
|
263 if(iOrientation) |
|
264 {// log landscape |
|
265 TBuf8<KBuffer128> buf; |
|
266 buf.Copy(KLandscape); |
|
267 WriteFile(buf); |
|
268 } |
|
269 iOrientation = EFalse; |
|
270 } |
|
271 } |
|
272 break; |
|
273 // Reset camera button's state flag |
|
274 case RClientCommander::ETaskExisted: |
|
275 { |
|
276 iCameraButtonPressed = EFalse; |
|
277 } |
|
278 break; |
|
279 default: |
|
280 {} |
|
281 break; |
|
282 } |
|
283 |
|
284 return 0; |
|
285 } |
|
286 |
|
287 TInt CServerCtrl::CommandReplyL( TInt /*aCode*/) |
|
288 { |
|
289 return 0; |
|
290 } |
|
291 |
|
292 void CServerCtrl::Command( TInt /*aCode*/, TAny* /* aArgs */ ) |
|
293 { |
|
294 } |
|
295 void CServerCtrl::Redraw() |
|
296 { |
|
297 } |
|
298 void CServerCtrl::Animate( TDateTime* /* aDT */ ) |
|
299 { |
|
300 } |
|
301 void CServerCtrl::FocusChanged( TBool /* aState */ ) |
|
302 { |
|
303 } |
|
304 |
|
305 // ---------------------------------------------------------------------------------- |
|
306 // OfferRawEvent is called by Window Server when an event occurs (key press, pointer event) |
|
307 // ---------------------------------------------------------------------------------- |
|
308 // |
|
309 TBool CServerCtrl::OfferRawEvent( const TRawEvent& aRawEvent ) |
|
310 { |
|
311 if (iRecord) |
|
312 { |
|
313 // Pointer down |
|
314 if(aRawEvent.Type() == TRawEvent::EButton1Down) |
|
315 { |
|
316 // Convert coordinates if needed |
|
317 // Check elapsed time and write it to buffer |
|
318 CheckTimerInsertWait(); |
|
319 // Write button down event to buffer |
|
320 TBuf8<KBuffer128> buf; |
|
321 buf.Format(KStrPointerDown,aRawEvent.Pos().iX,aRawEvent.Pos().iY); |
|
322 WriteFile(buf); |
|
323 } |
|
324 // Drag event occured |
|
325 if(aRawEvent.Type() == TRawEvent::EPointerMove) |
|
326 { |
|
327 CheckTimerInsertWait(); |
|
328 TBuf8<KBuffer128> buf; |
|
329 buf.Format(KStrDrag,aRawEvent.Pos().iX,aRawEvent.Pos().iY); |
|
330 WriteFile(buf); |
|
331 } |
|
332 // Pointer released |
|
333 if(aRawEvent.Type() == TRawEvent::EButton1Up) |
|
334 { |
|
335 CheckTimerInsertWait(); |
|
336 TBuf8<KBuffer128> buf; |
|
337 buf.Format(KStrPointerUp,aRawEvent.Pos().iX,aRawEvent.Pos().iY); |
|
338 WriteFile(buf); |
|
339 } |
|
340 // Button pressed |
|
341 if(aRawEvent.Type() == TRawEvent::EKeyDown) |
|
342 { |
|
343 // camera button pressed, write screen shot command to buffer |
|
344 if(aRawEvent.ScanCode() == 227 || aRawEvent.ScanCode() == 171 ) |
|
345 { |
|
346 TBuf8<KBuffer256> buf; |
|
347 TTime Now; |
|
348 Now.HomeTime(); |
|
349 buf.Copy(KScreenShot1); |
|
350 buf.Append(iAppName); |
|
351 buf.AppendFormat(KScreenShot2, Now.Int64()); |
|
352 |
|
353 WriteFile(buf); |
|
354 |
|
355 iCameraButtonPressed = ETrue; |
|
356 } |
|
357 else |
|
358 { |
|
359 // Start to count time while button is pressed |
|
360 iSecCounter = 0; |
|
361 iCaptureKeyTimer->After(KWait08); // 0.8 sec |
|
362 } |
|
363 } |
|
364 |
|
365 |
|
366 // Button released |
|
367 if(aRawEvent.Type() == TRawEvent::EKeyUp) |
|
368 { |
|
369 iCaptureKeyTimer->Cancel(); |
|
370 |
|
371 TBuf8<KBuffer256> buf; |
|
372 // Write pressed key to buffer |
|
373 if(aRawEvent.ScanCode()>47 && aRawEvent.ScanCode()<=57) |
|
374 buf.Format(KStr,iSecCounter,aRawEvent.ScanCode()-48); |
|
375 if(aRawEvent.ScanCode()==EStdKeyUpArrow) |
|
376 buf.Format(KUp,iSecCounter); |
|
377 if(aRawEvent.ScanCode()==EStdKeyDownArrow) |
|
378 buf.Format(KDown,iSecCounter); |
|
379 if(aRawEvent.ScanCode()==EStdKeyRightArrow) |
|
380 buf.Format(KRight,iSecCounter); |
|
381 if(aRawEvent.ScanCode()==EStdKeyLeftArrow) |
|
382 buf.Format(KLeft,iSecCounter); |
|
383 if(aRawEvent.ScanCode()==EStdKeyDevice0) |
|
384 buf.Format(KLSK,iSecCounter); |
|
385 if(aRawEvent.ScanCode()==EStdKeyDevice1) |
|
386 buf.Format(KRSK,iSecCounter); |
|
387 if(aRawEvent.ScanCode()==EStdKeyDevice3) |
|
388 buf.Format(KMSK,iSecCounter); |
|
389 if(aRawEvent.ScanCode()==EStdKeyBackspace) |
|
390 buf.Format(KBS,iSecCounter); |
|
391 if(aRawEvent.ScanCode()==KAsteriskKeyScanCode) |
|
392 buf.Format(KAsterisk,iSecCounter); |
|
393 if(aRawEvent.ScanCode()==EStdKeyYes) |
|
394 buf.Format(KYes,iSecCounter); |
|
395 if(aRawEvent.ScanCode()==EStdKeyNo) |
|
396 {// To filter first two 'No' keys (part of screen reset) |
|
397 if(iNoCount==0) |
|
398 { |
|
399 iNoCount++; |
|
400 iIsEventEnabled = ETrue; |
|
401 return EFalse; |
|
402 } |
|
403 |
|
404 buf.Format(KNo,iSecCounter); |
|
405 } |
|
406 if(aRawEvent.ScanCode()==EStdKeyHash) |
|
407 buf.Format(KHash,iSecCounter); |
|
408 if(aRawEvent.ScanCode()==EStdKeyApplication0) //MENU |
|
409 buf.Format(KTasks,iSecCounter); |
|
410 if(buf.Length()>0) |
|
411 { |
|
412 |
|
413 CheckTimerInsertWait(); |
|
414 WriteFile(buf); |
|
415 } |
|
416 // |
|
417 |
|
418 } |
|
419 |
|
420 |
|
421 } |
|
422 return EFalse; |
|
423 } |
|
424 // ------------------------------------------- |
|
425 // Count time while button is pressed |
|
426 // ------------------------------------------- |
|
427 // |
|
428 void CServerCtrl::KeyTimerExpired() |
|
429 { |
|
430 iSecCounter++; |
|
431 iCaptureKeyTimer->After(KWait08); // 0.8 sec |
|
432 } |
|
433 // -------------------------------------------------------------- |
|
434 // Inserts time interval between two events into the script |
|
435 // -------------------------------------------------------------- |
|
436 // |
|
437 void CServerCtrl::CheckTimerInsertWait() |
|
438 { |
|
439 TTime time; |
|
440 time.HomeTime(); |
|
441 |
|
442 TTimeIntervalMicroSeconds interval = time.MicroSecondsFrom(iWaitTimer); |
|
443 |
|
444 // If time interval is bigger than 100 micosecs then write it to buffer |
|
445 if( interval > 100 ) |
|
446 { |
|
447 TBuf8<KBuffer128> buf; |
|
448 buf.Format(KStrWait, interval.Int64() ); |
|
449 WriteFile(buf); |
|
450 } |
|
451 // Home time will be the previous time at next event |
|
452 iWaitTimer = time; |
|
453 } |
|
454 |
|
455 // -------------------------------------------------------------- |
|
456 // Implements a buffer. Writes to file only if buffer is full. |
|
457 // -------------------------------------------------------------- |
|
458 // |
|
459 void CServerCtrl::WriteFile(TDesC8& aBuf) |
|
460 { |
|
461 // It doesn't record till screen reset (2 NO key presses) is not over |
|
462 if(!iIsEventEnabled) |
|
463 return; |
|
464 |
|
465 TInt r=iMainBuffer->Length(); |
|
466 TInt t=aBuf.Length(); |
|
467 iMainBuffer = iMainBuffer->ReAlloc(r+t+1); |
|
468 TPtr8 bufferPtr( iMainBuffer->Des() ); |
|
469 bufferPtr.Append(aBuf); |
|
470 |
|
471 if(iWritePointer++ > KWriteBufferSize) |
|
472 { |
|
473 // Buffer is full. Write to file and reset buffer |
|
474 iWritePointer = 0; |
|
475 iRFile.Write(*iMainBuffer); |
|
476 delete iMainBuffer; |
|
477 iMainBuffer = NULL; |
|
478 TRAPD(err, iMainBuffer = HBufC8::NewL(1)); |
|
479 } |
|
480 } |
|
481 // End of File |