|
1 /* |
|
2 * Copyright (c) 2007,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: Generic upnp remote rendering state machine |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifndef C_UPNPRENDERINGSTATEMACHINE_H |
|
19 #define C_UPNPRENDERINGSTATEMACHINE_H |
|
20 |
|
21 // INCLUDES |
|
22 #include <e32base.h> |
|
23 #include "upnpavrenderingsessionobserver.h" // TUPnPAVInteractOperation |
|
24 #include "upnpresourceselector.h" // TUPnPSelectDefaultResource |
|
25 #include "upnprenderingstatemachineconstants.h" // types |
|
26 #include "upnprenderingoperationexecutor.h" |
|
27 |
|
28 // FORWARD DECLARATIONS |
|
29 class MUPnPAVRenderingSession; |
|
30 class MUpnpRenderingStateMachineObserver; |
|
31 class TUpnpRenderingOperation; |
|
32 class CUpnpRenderingPlaytimeCalculator; |
|
33 class CUpnpRenderingStateMachineStates; |
|
34 class CUpnpRenderingOperationQueue; |
|
35 class MUPnPResourceSelector; |
|
36 class CUpnpItem; |
|
37 class CPeriodic; |
|
38 |
|
39 // CONSTANTS |
|
40 const TInt KUriBuffer = 256; |
|
41 |
|
42 /** |
|
43 * Class for handling renderer states |
|
44 * |
|
45 * @lib upnprenderingstatemachine.lib |
|
46 */ |
|
47 class CUpnpRenderingStateMachine |
|
48 : public CBase |
|
49 , public MUpnpRenderingOperationExecutor |
|
50 { |
|
51 |
|
52 public: // construction / destruction |
|
53 |
|
54 /** |
|
55 * static constructor |
|
56 * |
|
57 * @param aSession session where to send volume events |
|
58 */ |
|
59 IMPORT_C static CUpnpRenderingStateMachine* NewL( |
|
60 MUPnPAVRenderingSession& aSession ); |
|
61 |
|
62 /** |
|
63 * Destructor |
|
64 */ |
|
65 IMPORT_C virtual ~CUpnpRenderingStateMachine(); |
|
66 |
|
67 private: // construction, private part |
|
68 |
|
69 /** |
|
70 * static constructor |
|
71 */ |
|
72 CUpnpRenderingStateMachine( |
|
73 MUPnPAVRenderingSession& aSession ); |
|
74 |
|
75 /** |
|
76 * 2nd phase constructor |
|
77 */ |
|
78 void ConstructL(); |
|
79 |
|
80 public: // the interface |
|
81 |
|
82 /** |
|
83 * sets the state machine options (future extension) |
|
84 * @param aOptions options bit mask |
|
85 */ |
|
86 IMPORT_C void SetOptions( TInt aOptions ); |
|
87 |
|
88 /** |
|
89 * returns current options |
|
90 * @return the options bitmask |
|
91 */ |
|
92 IMPORT_C TInt Options() const; |
|
93 |
|
94 /** |
|
95 * sets the state machine observer |
|
96 * @param aObserver the observer to set |
|
97 */ |
|
98 IMPORT_C void SetObserver( MUpnpRenderingStateMachineObserver& aObserver ); |
|
99 |
|
100 /** |
|
101 * removes the current observer |
|
102 */ |
|
103 IMPORT_C void RemoveObserver(); |
|
104 |
|
105 /** |
|
106 * sets the resource selector for media to play |
|
107 * if not called, TUPnPSelectDefaultResource will be used. |
|
108 */ |
|
109 IMPORT_C void SetResourceSelector( MUPnPResourceSelector& aSelector ); |
|
110 |
|
111 /** |
|
112 * Synchronises the state machine with the remote renderer |
|
113 * (updates the state) |
|
114 * this is an aynchronous operation and calls back RendererSyncReady() |
|
115 */ |
|
116 IMPORT_C void SyncL(); |
|
117 |
|
118 /** |
|
119 * Forces the state machine off sync |
|
120 * (sets the cached state to OffSync) |
|
121 */ |
|
122 IMPORT_C void SetOffSync(); |
|
123 |
|
124 /** |
|
125 * Checks if the state machine is synchronised |
|
126 * with the remote renderer ie. in operation |
|
127 * @return ETrue if state machine is operational |
|
128 */ |
|
129 IMPORT_C TBool IsInSync() const; |
|
130 |
|
131 /** |
|
132 * Executes a command on the renderer. |
|
133 * If a command is currently running, the command is queued. |
|
134 * see Upnp::TCommand on upnprenderingstatemachineconstants.h |
|
135 * @param aCommand the command to execute |
|
136 * @param aCommandParameter command-specific parameter |
|
137 * @param aMedia the media to be played (specific to PLAY command) |
|
138 */ |
|
139 IMPORT_C void CommandL( |
|
140 Upnp::TCommand aCommand, |
|
141 TInt aCommandParameter = 0, |
|
142 const CUpnpItem* aMedia = NULL |
|
143 ); |
|
144 |
|
145 /** |
|
146 * Checks if the state machine is busy executing a command |
|
147 * @return ETrue if the state machine is busy |
|
148 */ |
|
149 IMPORT_C TBool IsBusy() const; |
|
150 |
|
151 /** |
|
152 * Cancels currently ongoing operation and cleans up the |
|
153 * queue of operations |
|
154 */ |
|
155 IMPORT_C void Cancel(); |
|
156 |
|
157 /** |
|
158 * returns the current renderer state |
|
159 * Note: this is not a network operation - returns a cached value |
|
160 * @return the renderer state |
|
161 */ |
|
162 IMPORT_C Upnp::TState State() const; |
|
163 |
|
164 /** |
|
165 * returns current track duration. |
|
166 * Note: this is NOT a network operation - returns a cached value. |
|
167 * NOTE ALSO: The method only works in case ERenderingOptionAutoSyncPos |
|
168 * option is in use or ERenderingCommandSyncPos has been called to |
|
169 * synchronise the position/duration. |
|
170 * @return the current track duration, or -1 if it is not available |
|
171 */ |
|
172 IMPORT_C TInt Duration() const; |
|
173 |
|
174 /** |
|
175 * returns current position within the track. |
|
176 * Note: this is NOT a network operation - returns the position within an |
|
177 * internal position timer. The timer can be calibrated with the renderer |
|
178 * position using ECalibrate command, after which the Position values are |
|
179 * again more accurate. |
|
180 * @return the current estimated position, or -1 if it is not available |
|
181 */ |
|
182 IMPORT_C TInt Position() const; |
|
183 |
|
184 /** |
|
185 * Tests if this renderer has pause capability. |
|
186 * Requesting PAUSE for a renderer that does not have this capability |
|
187 * wil result into an error. |
|
188 * @return ETrue if device has volume control capability. |
|
189 */ |
|
190 IMPORT_C TBool HasPauseCapability() const; |
|
191 |
|
192 public: // methods like in MUPnPRenderingSessionObserver |
|
193 |
|
194 /** |
|
195 * @see MUPnPRenderiongSessionObserver |
|
196 * client of this state machine should forward the corresponding method |
|
197 * from the rendering session directly to this method |
|
198 */ |
|
199 IMPORT_C void InteractOperationComplete( |
|
200 TInt aError, TUPnPAVInteractOperation aOperation ); |
|
201 |
|
202 /** |
|
203 * @see MUPnPRenderiongSessionObserver |
|
204 * client of this state machine should forward the corresponding method |
|
205 * from the rendering session directly to this method |
|
206 */ |
|
207 IMPORT_C void PositionInfoResult( |
|
208 TInt aError, const TDesC8& aPosition, const TDesC8& aLength ); |
|
209 |
|
210 /** |
|
211 * @see MUPnPRenderiongSessionObserver |
|
212 * client of this state machine should forward the corresponding method |
|
213 * from the rendering session directly to this method |
|
214 */ |
|
215 IMPORT_C void SetURIResult( TInt aError ); |
|
216 |
|
217 /** |
|
218 * @see MUPnPRenderiongSessionObserver |
|
219 * client of this state machine should forward the corresponding method |
|
220 * from the rendering session directly to this method |
|
221 */ |
|
222 IMPORT_C void SetNextURIResult( TInt aError ); |
|
223 |
|
224 public: // internal methods for the state algorithms |
|
225 |
|
226 /** |
|
227 * Reports SynReady to observer |
|
228 */ |
|
229 void ReportSyncReady( TInt aError, |
|
230 Upnp::TState aNewState ); |
|
231 |
|
232 /** |
|
233 * Reports StateChanged to observers |
|
234 */ |
|
235 void ReportStateChanged( TInt aError, |
|
236 Upnp::TState aNewState, |
|
237 TBool aActionResponse = ETrue, |
|
238 TInt aStateParam = 0 ); |
|
239 |
|
240 /** |
|
241 * Reports PositionSync to observers |
|
242 */ |
|
243 void ReportPositionSync( TInt aError, |
|
244 Upnp::TPositionMode aMode, |
|
245 TInt aDuration, TInt aPosition ); |
|
246 |
|
247 private: // data |
|
248 |
|
249 // Rendering session |
|
250 MUPnPAVRenderingSession& iSession; |
|
251 |
|
252 // the observer (no ownership!) |
|
253 MUpnpRenderingStateMachineObserver* iObserver; |
|
254 |
|
255 // the current state |
|
256 Upnp::TState iState; |
|
257 |
|
258 // rendering state machine option flags |
|
259 TInt iOptions; |
|
260 |
|
261 // playtime calculator |
|
262 CUpnpRenderingPlaytimeCalculator* iPlaytimeCalculator; |
|
263 |
|
264 // state when buffering started with 'set uri' request |
|
265 Upnp::TState iStateBeforeSetUri; |
|
266 |
|
267 |
|
268 /************************** |
|
269 ** State machine states ** |
|
270 **************************/ |
|
271 |
|
272 public: // Operation execution methods |
|
273 |
|
274 /** |
|
275 * from MUpnpRenderingOperationExecutor |
|
276 */ |
|
277 TResult ExecuteOperationL( |
|
278 const TUpnpRenderingOperation& aOperation, |
|
279 const TUpnpRenderingOperation& aCurrent ); |
|
280 |
|
281 /** |
|
282 * from MUpnpRenderingOperationExecutor |
|
283 */ |
|
284 TResult ProcessOperationL( |
|
285 const TUpnpRenderingOperation& aOperation, TInt aEvent, |
|
286 TInt aError, const TAny* aParam1, const TAny* aParam2 ); |
|
287 |
|
288 /** |
|
289 * from MUpnpRenderingOperationExecutor |
|
290 */ |
|
291 void HandleAsyncError( |
|
292 const TUpnpRenderingOperation& aOperation, TInt aError ); |
|
293 |
|
294 /** |
|
295 * processing events |
|
296 * used in context of the operation queue |
|
297 */ |
|
298 enum TOperationEvents |
|
299 { |
|
300 EInteractOperationComplete, |
|
301 EPositionInfo, |
|
302 ESetUriResult, |
|
303 ETimeout |
|
304 }; |
|
305 |
|
306 private: // internal state machinery |
|
307 |
|
308 // these are all called from the operation queue. |
|
309 // in all below methods, aOperation is the currently ongoing operation. |
|
310 |
|
311 // executes an operation |
|
312 TResult ExecuteOperationSyncL( |
|
313 const TUpnpRenderingOperation& aOperation, |
|
314 const TUpnpRenderingOperation& aCurrent ); |
|
315 TResult ExecuteOperationPlayL( |
|
316 const TUpnpRenderingOperation& aOperation, |
|
317 const TUpnpRenderingOperation& aCurrent ); |
|
318 TResult ExecuteOperationStopL( |
|
319 const TUpnpRenderingOperation& aOperation, |
|
320 const TUpnpRenderingOperation& aCurrent ); |
|
321 TResult ExecuteOperationPauseL( |
|
322 const TUpnpRenderingOperation& aOperation, |
|
323 const TUpnpRenderingOperation& aCurrent ); |
|
324 TResult ExecuteOperationResumeL( |
|
325 const TUpnpRenderingOperation& aOperation, |
|
326 const TUpnpRenderingOperation& aCurrent ); |
|
327 TResult ExecuteOperationRestartL( |
|
328 const TUpnpRenderingOperation& aOperation, |
|
329 const TUpnpRenderingOperation& aCurrent ); |
|
330 TResult ExecuteOperationSeekL( |
|
331 const TUpnpRenderingOperation& aOperation, |
|
332 const TUpnpRenderingOperation& aCurrent ); |
|
333 TResult ExecuteOperationCalibrateL( |
|
334 const TUpnpRenderingOperation& aOperation, |
|
335 const TUpnpRenderingOperation& aCurrent ); |
|
336 TResult ExecuteOperationSetUriL( |
|
337 const TUpnpRenderingOperation& aOperation, |
|
338 const TUpnpRenderingOperation& aCurrent ); |
|
339 |
|
340 // handles network events |
|
341 TResult ProcessPositionInfo( |
|
342 const TUpnpRenderingOperation& aOperation, |
|
343 TInt aError, const TDesC8& aPosition, const TDesC8& aLength ); |
|
344 TResult ProcessSetURIResultL( |
|
345 const TUpnpRenderingOperation& aOperation, TInt aError ); |
|
346 TResult ProcessAVEvents( |
|
347 const TUpnpRenderingOperation& aOperation, |
|
348 const TUPnPAVInteractOperation aIntOp, |
|
349 TInt aError ); |
|
350 |
|
351 protected: // internal |
|
352 |
|
353 // retrieves a resource from given media using the media selector |
|
354 const CUpnpElement& ResourceFromL( const CUpnpItem& aMedia ); |
|
355 |
|
356 |
|
357 // user-defined resource selector (NOT OWNED!) |
|
358 MUPnPResourceSelector* iSelector; |
|
359 |
|
360 // the default resource selector (used if not explicitly set by user) |
|
361 TUPnPSelectDefaultResource iDefaultSelector; |
|
362 |
|
363 // currently playing HTTP URI |
|
364 TBuf8<KUriBuffer> iCurrentUri; |
|
365 |
|
366 |
|
367 /*********** |
|
368 ** Queue ** |
|
369 ***********/ |
|
370 public: // methods |
|
371 |
|
372 /** |
|
373 * Count of operations in the queue |
|
374 * @return count of operations in the queue |
|
375 */ |
|
376 TInt Size() const; |
|
377 |
|
378 /** |
|
379 * Checks if the queue is free for new operations |
|
380 * @return ETrue if new operation can be run immediately |
|
381 */ |
|
382 TBool IsFree() const; |
|
383 |
|
384 /** |
|
385 * push operation to queue. |
|
386 * Don't even try to execute it at this stage. |
|
387 * @param aOperation the operation to be added |
|
388 */ |
|
389 void PushL( |
|
390 const TUpnpRenderingOperation& aOperation ); |
|
391 |
|
392 /** |
|
393 * push operation to queue and execute |
|
394 * @param aOperation the operation to be added |
|
395 */ |
|
396 void PushAndExecuteL( |
|
397 const TUpnpRenderingOperation& aOperation ); |
|
398 |
|
399 /** |
|
400 * executes the first operation in the queue |
|
401 * note: non-leaving version. |
|
402 * if the operation completes, continues recursively to next |
|
403 * until queue is empty |
|
404 */ |
|
405 void Execute(); |
|
406 |
|
407 /** |
|
408 * Processes an item in the queue with given data |
|
409 * if the operation completes, continues recursively to next |
|
410 * until queue is empty |
|
411 */ |
|
412 void Process( TInt aEvent, |
|
413 TInt aError=0, const TAny* aParam1=NULL, const TAny* aParam2=NULL ); |
|
414 |
|
415 /** |
|
416 * Finds and removes deprecated commands from queue. |
|
417 * E.g. If the last command is stop, then all other except the current |
|
418 * (ongoing) and the stop command are removed. |
|
419 */ |
|
420 void CompressQueueL(); |
|
421 |
|
422 /** |
|
423 * removes all dup. commands but not the latest one and ongoing |
|
424 * |
|
425 * @param aCommand commands to be removed from queue |
|
426 */ |
|
427 void RemoveAllDublicateCommands( Upnp::TCommand aCommand ); |
|
428 |
|
429 public: // own methods |
|
430 |
|
431 /** |
|
432 * Returns currently ongoing operation. ENone, if queue empty |
|
433 * @return operation at first position |
|
434 */ |
|
435 TUpnpRenderingOperation Current() const; |
|
436 |
|
437 |
|
438 /** |
|
439 * executes the current operation recursively |
|
440 * if the operation completes, continues recursively to next |
|
441 * until queue is empty |
|
442 */ |
|
443 void ExecuteRecursivelyL(); |
|
444 |
|
445 /** |
|
446 * executes an operation parallel to an ongoing operation |
|
447 */ |
|
448 void ExecuteParallelL( |
|
449 const TUpnpRenderingOperation& aOperation ); |
|
450 |
|
451 private: |
|
452 |
|
453 void SetUriL( const TUpnpRenderingOperation& aOperation ); |
|
454 |
|
455 private: |
|
456 |
|
457 // the array that implements the queue |
|
458 RArray<TUpnpRenderingOperation> iQueue; |
|
459 |
|
460 // Seek position to be used for playbacktimecalculator |
|
461 // when seek is completed |
|
462 TInt iSeekPostion; |
|
463 |
|
464 // Start timestamp for getting position; it is used to add |
|
465 // half of the delay when get position request is made and |
|
466 // when the response is received to avoid lag with the renderer |
|
467 TTime iGetPositionStartMark; |
|
468 |
|
469 }; |
|
470 |
|
471 |
|
472 #endif // C_UPNPRENDERINGSTATEMACHINE_H |
|
473 |