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: Music Player now playing widget backend - Private. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <mpxplaybackutility.h> |
|
19 #include <mpxplaybackframeworkdefs.h> |
|
20 #include <mpxmediageneraldefs.h> |
|
21 #include <mpxmediamusicdefs.h> |
|
22 #include <mpxcommandgeneraldefs.h> |
|
23 #include <mpxplaybackmessage.h> |
|
24 #include <mpxmessagegeneraldefs.h> |
|
25 #include <mpxplaybackmessagedefs.h> |
|
26 |
|
27 #include <QString> |
|
28 |
|
29 #include "mpnowplayingbackend_p.h" |
|
30 #include "mptrace.h" |
|
31 |
|
32 /*! |
|
33 \internal |
|
34 \class MpNowPlayingBackEndPrivate |
|
35 \brief Wraps the playback utility and provides separation for QT and Symbian code. |
|
36 |
|
37 This class wraps the playback utility on the MPX Framework to provide a simple |
|
38 interface and separation of QT and Symbian code. |
|
39 */ |
|
40 |
|
41 |
|
42 /*! |
|
43 \internal |
|
44 Constructs the now playing back end private. |
|
45 */ |
|
46 MpNowPlayingBackEndPrivate::MpNowPlayingBackEndPrivate( long int playerId, MpNowPlayingBackEnd *qq ) |
|
47 : q_ptr( qq ), |
|
48 mPreviousState( NotPlaying ), |
|
49 mPlaybackUtility(0) |
|
50 { |
|
51 TX_ENTRY_ARGS( "Player ID =" << playerId << " Q pointer=" << ( void * )qq ) |
|
52 if ( !playerId ) { |
|
53 playerId = KPbModeDefault.iUid; |
|
54 } |
|
55 TRAPD( errCode, |
|
56 mPlaybackUtility = MMPXPlaybackUtility::UtilityL( TUid::Uid( playerId ) ); |
|
57 mPlaybackUtility->AddObserverL( *this ); |
|
58 ); |
|
59 |
|
60 if( KErrNone != errCode && mPlaybackUtility ) { |
|
61 mPlaybackUtility->Close(); |
|
62 mPlaybackUtility = 0; |
|
63 } |
|
64 TX_EXIT |
|
65 } |
|
66 |
|
67 /*! |
|
68 \internal |
|
69 Destructs the now playing back end private. |
|
70 */ |
|
71 MpNowPlayingBackEndPrivate::~MpNowPlayingBackEndPrivate() |
|
72 { |
|
73 TX_ENTRY |
|
74 if ( mPlaybackUtility ) { |
|
75 TRAP_IGNORE( mPlaybackUtility->RemoveObserverL( *this ) ); |
|
76 mPlaybackUtility->Close(); |
|
77 } |
|
78 TX_EXIT |
|
79 } |
|
80 |
|
81 /*! |
|
82 \internal |
|
83 Updates the widget with the latest playback information. |
|
84 */ |
|
85 void MpNowPlayingBackEndPrivate::update() |
|
86 { |
|
87 TX_ENTRY |
|
88 TRAPD( errCode, UpdateStateL() ); |
|
89 if ( KErrNone == errCode ) { |
|
90 TRAP_IGNORE( RequestMediaL() ); |
|
91 } |
|
92 TX_EXIT |
|
93 } |
|
94 |
|
95 /*! |
|
96 \internal |
|
97 Sends a play/pause command. |
|
98 */ |
|
99 void MpNowPlayingBackEndPrivate::playPause() |
|
100 { |
|
101 TX_ENTRY |
|
102 TRAPD(err, DoPlayPauseL()); |
|
103 if ( err != KErrNone ) { |
|
104 TX_LOG_ARGS("Error: " << err << "; should never get here."); |
|
105 } |
|
106 TX_EXIT |
|
107 } |
|
108 |
|
109 /*! |
|
110 \internal |
|
111 Callback function from MMPXPlaybackObserver. |
|
112 \sa DoHandlePlaybackMessageL() |
|
113 */ |
|
114 void MpNowPlayingBackEndPrivate::HandlePlaybackMessage( |
|
115 CMPXMessage* aMessage, |
|
116 TInt aError ) |
|
117 { |
|
118 TX_ENTRY |
|
119 if ( aError == KErrNone && aMessage ) { |
|
120 TRAP_IGNORE( DoHandlePlaybackMessageL( *aMessage ) ); |
|
121 } |
|
122 TX_EXIT |
|
123 } |
|
124 |
|
125 /*! |
|
126 \internal |
|
127 Callback function from MMPXPlaybackObserver. |
|
128 */ |
|
129 void MpNowPlayingBackEndPrivate::HandlePropertyL( TMPXPlaybackProperty aProperty, |
|
130 TInt aValue, TInt aError) |
|
131 { |
|
132 // Nothing to do. |
|
133 Q_UNUSED(aProperty); |
|
134 Q_UNUSED(aValue); |
|
135 Q_UNUSED(aError); |
|
136 } |
|
137 |
|
138 /*! |
|
139 \internal |
|
140 Callback function from MMPXPlaybackObserver. |
|
141 */ |
|
142 void MpNowPlayingBackEndPrivate::HandleSubPlayerNamesL( TUid aPlayer, |
|
143 const MDesCArray* aSubPlayers, TBool aComplete, TInt aError ) |
|
144 { |
|
145 // Nothing to do. |
|
146 Q_UNUSED(aPlayer); |
|
147 Q_UNUSED(aSubPlayers); |
|
148 Q_UNUSED(aComplete); |
|
149 Q_UNUSED(aError); |
|
150 } |
|
151 |
|
152 /*! |
|
153 \internal |
|
154 Callback function from MMPXPlaybackCallback. |
|
155 */ |
|
156 void MpNowPlayingBackEndPrivate::HandleMediaL( |
|
157 const CMPXMedia& aMedia, |
|
158 TInt aError ) |
|
159 { |
|
160 TX_ENTRY |
|
161 if( KErrNone != aError || mPreviousState == NotPlaying ) { |
|
162 TX_EXIT |
|
163 return; |
|
164 } |
|
165 |
|
166 if( aMedia.IsSupported( KMPXMediaGeneralTitle ) ) { |
|
167 emit q_ptr->titleChanged( |
|
168 QString::fromUtf16( aMedia.ValueText( KMPXMediaGeneralTitle ).Ptr(), |
|
169 aMedia.ValueText( KMPXMediaGeneralTitle ).Length() ) ); |
|
170 } |
|
171 else if (aMedia.IsSupported( KMPXMediaGeneralUri )) { |
|
172 TParsePtrC filePath( aMedia.ValueText( KMPXMediaGeneralUri ) ); |
|
173 emit q_ptr->titleChanged( |
|
174 QString::fromUtf16( filePath.Name().Ptr(), |
|
175 filePath.Name().Length() ) ); |
|
176 } |
|
177 else { |
|
178 emit q_ptr->titleChanged( QString() ); |
|
179 } |
|
180 |
|
181 if( aMedia.IsSupported( KMPXMediaMusicArtist ) ) { |
|
182 emit q_ptr->artistChanged( |
|
183 QString::fromUtf16( aMedia.ValueText( KMPXMediaMusicArtist ).Ptr(), |
|
184 aMedia.ValueText( KMPXMediaMusicArtist ).Length() ) ); |
|
185 } |
|
186 else { |
|
187 emit q_ptr->artistChanged( QString() ); |
|
188 } |
|
189 TX_EXIT |
|
190 } |
|
191 |
|
192 /*! |
|
193 \internal |
|
194 Leaving function to request Media. |
|
195 \sa HandleMediaL() |
|
196 */ |
|
197 void MpNowPlayingBackEndPrivate::RequestMediaL() |
|
198 { |
|
199 TX_ENTRY |
|
200 MMPXSource* mediaSrc = mPlaybackUtility->Source(); |
|
201 User::LeaveIfNull( mediaSrc ); |
|
202 RArray<TMPXAttribute> requestedAttr; |
|
203 CleanupClosePushL( requestedAttr ); |
|
204 requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralTitle ) ); |
|
205 requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicArtist ) ); |
|
206 requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralUri ) ); |
|
207 mediaSrc->MediaL( requestedAttr.Array(), *this ); |
|
208 CleanupStack::PopAndDestroy( &requestedAttr ); |
|
209 TX_EXIT |
|
210 } |
|
211 |
|
212 /*! |
|
213 \internal |
|
214 Leaving function to update the playback state. |
|
215 */ |
|
216 void MpNowPlayingBackEndPrivate::UpdateStateL() |
|
217 { |
|
218 TX_ENTRY |
|
219 if ( !mPlaybackUtility->Source() ) { |
|
220 TX_LOG_ARGS( "NotPlaying" ) |
|
221 mPreviousState = NotPlaying; |
|
222 emit q_ptr->stateUpdate( NotPlaying ); |
|
223 |
|
224 } |
|
225 else { |
|
226 TMPXPlaybackState state = mPlaybackUtility->StateL(); |
|
227 switch ( state ) { |
|
228 case EPbStatePlaying: |
|
229 if ( mPreviousState != Playing ) { |
|
230 TX_LOG_ARGS( "Playing" ) |
|
231 emit q_ptr->stateUpdate( Playing ); |
|
232 } |
|
233 mPreviousState = Playing; |
|
234 break; |
|
235 case EPbStatePaused: |
|
236 case EPbStateStopped: //reinterpreting stop as a pause |
|
237 TX_LOG_ARGS("EPbStatePaused or PbStateStopped") |
|
238 if (mPreviousState != Paused){ |
|
239 TX_LOG_ARGS( "Paused" ) |
|
240 emit q_ptr->stateUpdate( Paused ); |
|
241 } |
|
242 mPreviousState = Paused; |
|
243 break; |
|
244 default: |
|
245 //Ignore other states. |
|
246 break; |
|
247 } |
|
248 } |
|
249 TX_EXIT |
|
250 } |
|
251 |
|
252 /*! |
|
253 \internal |
|
254 Leaving function to send play/pause command. |
|
255 */ |
|
256 void MpNowPlayingBackEndPrivate::DoPlayPauseL() |
|
257 { |
|
258 mPlaybackUtility->CommandL( EPbCmdPlayPause ); |
|
259 } |
|
260 |
|
261 /*! |
|
262 \internal |
|
263 Leaving function to handle the playback /a message. |
|
264 \sa HandlePlaybackMessageL() |
|
265 */ |
|
266 void MpNowPlayingBackEndPrivate::DoHandlePlaybackMessageL( |
|
267 const CMPXMessage& message ) |
|
268 { |
|
269 TX_ENTRY |
|
270 TMPXMessageId id( message.ValueTObjectL<TMPXMessageId>( KMPXMessageGeneralId ) ); |
|
271 if ( KMPXMessageGeneral == id ) { |
|
272 switch ( message.ValueTObjectL<TInt>( KMPXMessageGeneralEvent ) ) { |
|
273 case TMPXPlaybackMessage::EStateChanged: |
|
274 TX_LOG_ARGS( "EStateChanged" ) |
|
275 UpdateStateL(); |
|
276 break; |
|
277 case TMPXPlaybackMessage::EMediaChanged: |
|
278 TX_LOG_ARGS( "EMediaChanged or fall through from EPlaylistUpdated" ) |
|
279 RequestMediaL(); |
|
280 break; |
|
281 case TMPXPlaybackMessage::EPlaylistUpdated: |
|
282 TX_LOG_ARGS( "EPlaylistUpdated" ) |
|
283 case TMPXPlaybackMessage::EActivePlayerChanged: |
|
284 TX_LOG_ARGS( "EActivePlayerChanged or fall through from EPlaylistUpdated" ) |
|
285 UpdateStateL(); |
|
286 RequestMediaL(); |
|
287 break; |
|
288 default: |
|
289 TX_LOG_ARGS( "unhandled case:" << message.ValueTObjectL<TInt>( KMPXMessageGeneralEvent ) << "see TMPXPlaybackMessage" ) |
|
290 break; |
|
291 } |
|
292 } |
|
293 TX_EXIT |
|
294 } |
|