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: |
|
15 * |
|
16 */ |
|
17 |
|
18 // System includes |
|
19 #include <QTimer> |
|
20 #include <QRegExp> |
|
21 |
|
22 // User includes |
|
23 #include "radiomonitorservice.h" |
|
24 #include "radiouiengine.h" |
|
25 #include "radiouiengine_p.h" |
|
26 #include "radiostationmodel.h" |
|
27 #include "radioenginewrapper.h" |
|
28 #include "radioscannerengine.h" |
|
29 #include "radiostation.h" |
|
30 #include "radioservicedef.h" |
|
31 #include "radionotificationdata.h" |
|
32 #include "radiologger.h" |
|
33 |
|
34 // Constants |
|
35 const int NOTIFICATION_DELAY = 200; |
|
36 |
|
37 #define RUN_NOTIFY( type, data ) \ |
|
38 do { \ |
|
39 QVariant variant; \ |
|
40 variant.setValue( RadioNotificationData( RadioServiceNotification::type, data ) ); \ |
|
41 notify( variant ); \ |
|
42 } while ( 0 ) |
|
43 |
|
44 /*! |
|
45 * |
|
46 */ |
|
47 RadioMonitorService::RadioMonitorService( RadioUiEnginePrivate& engine ) : |
|
48 XQServiceProvider( RADIO_SERVICE +"."+ RADIO_MONITOR_SERVICE, &engine.api() ), |
|
49 mUiEngine( engine ), |
|
50 mRadioStatus( RadioStatus::UnSpecified ), |
|
51 mNotificationTimer( new QTimer( this ) ) |
|
52 { |
|
53 mNotificationTimer->setSingleShot( true ); |
|
54 mNotificationTimer->setInterval( NOTIFICATION_DELAY ); |
|
55 Radio::connect( mNotificationTimer, SIGNAL(timeout()), |
|
56 this, SLOT(sendNotifications()) ); |
|
57 |
|
58 publishAll(); |
|
59 } |
|
60 |
|
61 /*! |
|
62 * |
|
63 */ |
|
64 RadioMonitorService::~RadioMonitorService() |
|
65 { |
|
66 } |
|
67 |
|
68 /*! |
|
69 * |
|
70 */ |
|
71 void RadioMonitorService::init() |
|
72 { |
|
73 RadioStationModel* stationModel = &mUiEngine.api().stationModel(); |
|
74 Radio::connect( stationModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
|
75 this, SLOT(notifyFavoriteCount()) ); |
|
76 Radio::connect( stationModel, SIGNAL(favoriteChanged(RadioStation)), |
|
77 this, SLOT(notifyFavoriteCount()) ); |
|
78 Radio::connect( stationModel, SIGNAL(stationDataChanged(RadioStation)), |
|
79 this, SLOT(notifyStationChange(RadioStation)) ); |
|
80 Radio::connect( stationModel, SIGNAL(radioTextReceived(RadioStation)), |
|
81 this, SLOT(notifyStationChange(RadioStation)) ); |
|
82 |
|
83 RadioUiEngine* uiEngine = &mUiEngine.api(); |
|
84 Radio::connect( uiEngine, SIGNAL(seekingStarted(int)), |
|
85 this, SLOT(notifyRadioStatus()) ); |
|
86 Radio::connect( uiEngine, SIGNAL(muteChanged(bool)), |
|
87 this, SLOT(notifyRadioStatus()) ); |
|
88 Radio::connect( uiEngine, SIGNAL(antennaStatusChanged(bool)), |
|
89 this, SLOT(notifyRadioStatus()) ); |
|
90 Radio::connect( uiEngine, SIGNAL(powerOffRequested()), |
|
91 this, SLOT(notifyRadioStatus()) ); |
|
92 |
|
93 mUiEngine.wrapper().addObserver( this ); |
|
94 |
|
95 notifyRadioStatus(); |
|
96 } |
|
97 |
|
98 /*! |
|
99 * Public slot |
|
100 * |
|
101 */ |
|
102 void RadioMonitorService::requestNotifications() |
|
103 { |
|
104 //TODO: Uncomment when vendor id can be read from the client |
|
105 // if ( requestInfo().clientVendorId() == NOKIA_VENDORID ) { |
|
106 mRequestIndexes.append( setCurrentRequestAsync() ); |
|
107 // } |
|
108 } |
|
109 |
|
110 /*! |
|
111 * Public slot |
|
112 * |
|
113 */ |
|
114 void RadioMonitorService::requestAllData() |
|
115 { |
|
116 RadioStationModel& stationModel = mUiEngine.api().stationModel(); |
|
117 const RadioStation station = stationModel.currentStation(); |
|
118 |
|
119 QVariantList notificationList; |
|
120 QVariant notification; |
|
121 |
|
122 RadioStatus::Status radioStatus = determineRadioStatus(); |
|
123 notification.setValue( RadioNotificationData( RadioServiceNotification::RadioStatus, radioStatus ) ); |
|
124 notificationList.append( notification ); |
|
125 |
|
126 notification.setValue( RadioNotificationData( RadioServiceNotification::FavoriteCount, stationModel.favoriteCount() ) ); |
|
127 notificationList.append( notification ); |
|
128 |
|
129 notification.setValue( RadioNotificationData( RadioServiceNotification::Frequency, RadioStation::parseFrequency( station.frequency() ) ) ); |
|
130 notificationList.append( notification ); |
|
131 |
|
132 if ( !station.name().isEmpty() ) { |
|
133 notification.setValue( RadioNotificationData( RadioServiceNotification::Name, station.name() ) ); |
|
134 notificationList.append( notification ); |
|
135 } |
|
136 |
|
137 if ( station.genre() > 0 ) { |
|
138 notification.setValue( RadioNotificationData( RadioServiceNotification::Genre, |
|
139 mUiEngine.api().genreToString( station.genre(), GenreTarget::HomeScreen ) ) ); |
|
140 notificationList.append( notification ); |
|
141 } |
|
142 |
|
143 if ( !station.radioText().isEmpty() ) { |
|
144 const QString trimmedRadioText = trimHtmlTags( station.radioText() ); |
|
145 notification.setValue( RadioNotificationData( RadioServiceNotification::RadioText, trimmedRadioText ) ); |
|
146 notificationList.append( notification ); |
|
147 } |
|
148 |
|
149 if ( !station.dynamicPsText().isEmpty() ) { |
|
150 notification.setValue( RadioNotificationData( RadioServiceNotification::DynamicPS, station.dynamicPsText() ) ); |
|
151 notificationList.append( notification ); |
|
152 } |
|
153 |
|
154 checkIfCurrentStationIsFavorite(); |
|
155 |
|
156 completeRequest( setCurrentRequestAsync(), notificationList ); |
|
157 } |
|
158 |
|
159 /*! |
|
160 * Private slot |
|
161 */ |
|
162 void RadioMonitorService::notifyRadioStatus() |
|
163 { |
|
164 RadioStatus::Status radioStatus = determineRadioStatus(); |
|
165 |
|
166 if ( radioStatus != mRadioStatus ) { |
|
167 if ( radioStatus == RadioStatus::Seeking ) { |
|
168 if ( RadioScannerEngine* scannerEngine = mUiEngine.api().scannerEngine() ) { |
|
169 Radio::connect( scannerEngine, SIGNAL(destroyed()), |
|
170 this, SLOT(notifyRadioStatus()) ); |
|
171 } |
|
172 } |
|
173 |
|
174 mRadioStatus = radioStatus; |
|
175 RUN_NOTIFY( RadioStatus, radioStatus ); |
|
176 } |
|
177 } |
|
178 |
|
179 /*! |
|
180 * Private slot |
|
181 * |
|
182 */ |
|
183 void RadioMonitorService::notifyFavoriteCount() |
|
184 { |
|
185 const int favoriteCount = mUiEngine.api().stationModel().favoriteCount(); |
|
186 RUN_NOTIFY( FavoriteCount, favoriteCount ); |
|
187 |
|
188 if ( favoriteCount == 1 ) { |
|
189 checkIfCurrentStationIsFavorite(); |
|
190 } |
|
191 } |
|
192 |
|
193 /*! |
|
194 * Private slot |
|
195 * |
|
196 */ |
|
197 void RadioMonitorService::notifyStationChange( const RadioStation& station ) |
|
198 { |
|
199 RadioUiEngine& uiEngine = mUiEngine.api(); |
|
200 if ( uiEngine.isScanning() ) { |
|
201 return; |
|
202 } |
|
203 |
|
204 QVariantList list; |
|
205 QVariant notification; |
|
206 |
|
207 if ( station.hasDataChanged( RadioStation::GenreChanged ) ) { |
|
208 const QString genre = uiEngine.genreToString( station.genre(), GenreTarget::HomeScreen ); |
|
209 notification.setValue( RadioNotificationData( RadioServiceNotification::Genre, genre ) ); |
|
210 list.append( notification ); |
|
211 } |
|
212 |
|
213 if ( station.hasDataChanged( RadioStation::DynamicPsChanged ) ) { |
|
214 notification.setValue( RadioNotificationData( RadioServiceNotification::DynamicPS, station.dynamicPsText() ) ); |
|
215 list.append( notification ); |
|
216 } |
|
217 |
|
218 if ( station.hasDataChanged( RadioStation::NameChanged ) ) { |
|
219 notification.setValue( RadioNotificationData( RadioServiceNotification::Name, station.name() ) ); |
|
220 list.append( notification ); |
|
221 } |
|
222 |
|
223 if ( station.hasDataChanged( RadioStation::RadioTextChanged ) ) { |
|
224 const QString trimmedRadioText = trimHtmlTags( station.radioText() ); |
|
225 notification.setValue( RadioNotificationData( RadioServiceNotification::RadioText, trimmedRadioText ) ); |
|
226 list.append( notification ); |
|
227 } |
|
228 |
|
229 notifyList( list ); |
|
230 } |
|
231 |
|
232 /*! |
|
233 * Private slot |
|
234 * |
|
235 */ |
|
236 void RadioMonitorService::sendNotifications() |
|
237 { |
|
238 notifyList( mNotificationList ); |
|
239 mNotificationList.clear(); |
|
240 } |
|
241 |
|
242 /*! |
|
243 * \reimp |
|
244 */ |
|
245 void RadioMonitorService::tunedToFrequency( uint frequency, int reason ) |
|
246 { |
|
247 Q_UNUSED( reason ); |
|
248 if ( !mUiEngine.api().isScanning() ) { |
|
249 RUN_NOTIFY( Frequency, RadioStation::parseFrequency( frequency ) ); |
|
250 RadioStation station; |
|
251 if ( mUiEngine.api().stationModel().findFrequency( frequency, station ) && !station.name().isEmpty() ) { |
|
252 RUN_NOTIFY( Name, station.name() ); |
|
253 } |
|
254 |
|
255 const int favoriteCount = mUiEngine.api().stationModel().favoriteCount(); |
|
256 if ( favoriteCount == 1 ) { |
|
257 checkIfCurrentStationIsFavorite(); |
|
258 } |
|
259 } |
|
260 } |
|
261 |
|
262 /*! |
|
263 * |
|
264 */ |
|
265 RadioStatus::Status RadioMonitorService::determineRadioStatus() const |
|
266 { |
|
267 RadioUiEngine& uiEngine = mUiEngine.api(); |
|
268 if ( uiEngine.isPoweringOff() ) { |
|
269 return RadioStatus::PoweringOff; |
|
270 } else if ( uiEngine.isScanning() ) { |
|
271 return RadioStatus::Seeking; |
|
272 } else if ( !uiEngine.isAntennaAttached() ) { |
|
273 return RadioStatus::NoAntenna; |
|
274 } else if ( uiEngine.isMuted() ) { |
|
275 return RadioStatus::Muted; |
|
276 } |
|
277 |
|
278 return RadioStatus::Playing; |
|
279 } |
|
280 |
|
281 /*! |
|
282 * |
|
283 */ |
|
284 void RadioMonitorService::checkIfCurrentStationIsFavorite() |
|
285 { |
|
286 const bool currentIsFavorite = mUiEngine.api().stationModel().currentStation().isFavorite(); |
|
287 RUN_NOTIFY( CurrentIsFavorite, currentIsFavorite ); |
|
288 } |
|
289 |
|
290 /*! |
|
291 * |
|
292 */ |
|
293 QString RadioMonitorService::trimHtmlTags( const QString& html ) |
|
294 { |
|
295 QString trimmed = html; |
|
296 QRegExp rex( "<.+>" ); |
|
297 rex.setMinimal( true ); |
|
298 trimmed.remove( rex ); |
|
299 return trimmed; |
|
300 } |
|
301 |
|
302 /*! |
|
303 * |
|
304 */ |
|
305 void RadioMonitorService::notify( const QVariant& notification ) |
|
306 { |
|
307 mNotificationTimer->stop(); |
|
308 mNotificationList.append( notification ); |
|
309 mNotificationTimer->start(); |
|
310 } |
|
311 |
|
312 /*! |
|
313 * |
|
314 */ |
|
315 void RadioMonitorService::notifyList( const QVariantList& list ) |
|
316 { |
|
317 if ( mRequestIndexes.count() > 0 && list.count() > 0 ) { |
|
318 foreach ( int requestIndex, mRequestIndexes ) { |
|
319 completeRequest( requestIndex, list ); |
|
320 } |
|
321 mRequestIndexes.clear(); |
|
322 } |
|
323 } |
|