radioapp/radiouiengine/src/radiomonitorservice.cpp
branchRCL_3
changeset 19 cce62ebc198e
equal deleted inserted replaced
18:1a6714c53019 19:cce62ebc198e
       
     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 }