radioapp/radiouiengine/src/radiouiengine.cpp
branchRCL_3
changeset 20 93c594350b9a
parent 19 cce62ebc198e
equal deleted inserted replaced
19:cce62ebc198e 20:93c594350b9a
     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 <QScopedPointer>
       
    20 #include <QProcess>
       
    21 #include <QFile>
       
    22 #include <QTimer>
       
    23 #include <QDesktopServices>
       
    24 #include <QUrl>
       
    25 
       
    26 #ifdef BUILD_WIN32
       
    27 #   include <QSettings>
       
    28 #else
       
    29 #   include <XQSettingsManager>
       
    30 #endif // WIN32_BUILD
       
    31 
       
    32 // User includes
       
    33 #include "radiouiengine.h"
       
    34 #include "radiouiengine_p.h"
       
    35 #include "radioenginewrapper.h"
       
    36 #include "radiostationmodel.h"
       
    37 #include "radiohistorymodel.h"
       
    38 #include "radiohistoryitem.h"
       
    39 #include "radiosettings.h"
       
    40 #include "radioscannerengine.h"
       
    41 #include "radiogenrelocalizer.h"
       
    42 #include "radiologger.h"
       
    43 
       
    44 // Constants
       
    45 const uint RADIO_CENREP_UID = 0x2002FF52;
       
    46 const uint RADIO_CENREP_FREQUENCY_KEY = 0x207;
       
    47 const uint RADIO_CENREP_HEADSET_VOLUME = 0x200;
       
    48 
       
    49 const QLatin1String OVI_STORE_URL( "http://www.music.nokia.co.uk/Touch/Search.aspx?artistsearch=#artist#&titlesearch=#title#" );
       
    50 const QLatin1String OTHER_STORE_URL( "http://www.amazon.com/gp/search/ref=sr_adv_m_digital/?search-alias=digital-music&field-author=#artist#&field-title=#title#" );
       
    51 const QLatin1String OTHER_STORE_ARTIST_TAG( "#artist#" );
       
    52 const QLatin1String OTHER_STORE_TITLE_TAG( "#title#" );
       
    53 const char WHITESPACE = ' ';
       
    54 const char WHITESPACE_REPLACEMENT = '+';
       
    55 
       
    56 // Constants used when launching radio server
       
    57 const QLatin1String RADIO_SERVER_NAME( "radioserver.exe" );
       
    58 const QLatin1String RADIO_RANGE_USEURO( "useuro" );
       
    59 const QLatin1String RADIO_RANGE_JAPAN( "japan" );
       
    60 
       
    61 // ====== STATIC FUNCTIONS ========
       
    62 
       
    63 /*!
       
    64  * Gets the last tuned frequency from central repository
       
    65  */
       
    66 uint RadioUiEngine::lastTunedFrequency( uint defaultFrequency )
       
    67 {
       
    68     uint frequency = defaultFrequency;
       
    69 
       
    70 #ifdef BUILD_WIN32
       
    71     QScopedPointer<QSettings> settings( new QSettings( "Nokia", "QtFmRadio" ) );
       
    72     frequency = settings->value( "CurrentFreq", DEFAULT_MIN_FREQUENCY ).toUInt();
       
    73     if ( frequency == 0 ) {
       
    74         frequency = defaultFrequency;
       
    75     }
       
    76 #else
       
    77     QScopedPointer<XQSettingsManager> settings( new XQSettingsManager() );
       
    78     XQSettingsKey key( XQSettingsKey::TargetCentralRepository, RADIO_CENREP_UID, RADIO_CENREP_FREQUENCY_KEY );
       
    79     frequency = settings->readItemValue( key, XQSettingsManager::TypeInt ).toUInt();
       
    80     if ( frequency == 0 ) {
       
    81         frequency = defaultFrequency;
       
    82     }
       
    83 #endif
       
    84 
       
    85     return frequency;
       
    86 }
       
    87 
       
    88 /*!
       
    89  * Gets the last used volume level
       
    90  */
       
    91 int RadioUiEngine::lastVolume()
       
    92 {
       
    93     int volume = DEFAULT_VOLUME_LEVEL;
       
    94 
       
    95 #ifndef BUILD_WIN32
       
    96     QScopedPointer<XQSettingsManager> settings( new XQSettingsManager() );
       
    97     XQSettingsKey key( XQSettingsKey::TargetCentralRepository, RADIO_CENREP_UID, RADIO_CENREP_HEADSET_VOLUME );
       
    98     volume = settings->readItemValue( key, XQSettingsManager::TypeInt ).toInt();
       
    99     if ( volume == 0 ) {
       
   100         volume = DEFAULT_VOLUME_LEVEL;
       
   101     }
       
   102 #endif
       
   103 
       
   104     return volume;
       
   105 }
       
   106 
       
   107 /*!
       
   108  * Launches the radio server process
       
   109  */
       
   110 void RadioUiEngine::launchRadioServer()
       
   111 {
       
   112     QStringList args;
       
   113     args << RADIO_RANGE_USEURO; //TODO: Determine current region
       
   114     args << QString::number( lastTunedFrequency( 0 ) );
       
   115     args << QString::number( lastVolume() );
       
   116 
       
   117     QProcess serverProcess;
       
   118     bool success = serverProcess.startDetached( RADIO_SERVER_NAME, args );
       
   119     LOG_ASSERT( success, LOG( "Failed to start radio server!" ) );
       
   120 }
       
   121 
       
   122 // ====== MEMBER FUNCTIONS ========
       
   123 
       
   124 /*!
       
   125  *
       
   126  */
       
   127 RadioUiEngine::RadioUiEngine( QObject* parent ) :
       
   128     QObject( parent ),
       
   129     d_ptr( new RadioUiEnginePrivate( this ) )
       
   130 {
       
   131 }
       
   132 
       
   133 /*!
       
   134  *
       
   135  */
       
   136 RadioUiEngine::~RadioUiEngine()
       
   137 {
       
   138 }
       
   139 
       
   140 /*!
       
   141  *
       
   142  */
       
   143 bool RadioUiEngine::isInitialized() const
       
   144 {
       
   145     Q_D( const RadioUiEngine );
       
   146     return !d->mEngineWrapper.isNull();
       
   147 }
       
   148 
       
   149 /*!
       
   150  *
       
   151  */
       
   152 bool RadioUiEngine::init()
       
   153 {
       
   154     Q_D( RadioUiEngine );
       
   155     return d->init();
       
   156 }
       
   157 
       
   158 /*!
       
   159  *
       
   160  */
       
   161 bool RadioUiEngine::isFirstTimeStart()
       
   162 {
       
   163     Q_D( RadioUiEngine );
       
   164     return d->mEngineWrapper->settings().isFirstTimeStart();
       
   165 }
       
   166 
       
   167 /*!
       
   168  *
       
   169  */
       
   170 void RadioUiEngine::setFirstTimeStartPerformed( bool firstTimeStartPerformed )
       
   171 {
       
   172     Q_D( RadioUiEngine );
       
   173     d->mEngineWrapper->settings().setFirstTimeStartPerformed( firstTimeStartPerformed );
       
   174 }
       
   175 
       
   176 /*!
       
   177  *
       
   178  */
       
   179 void RadioUiEngine::setPowerOn()
       
   180 {
       
   181     setMute( false );
       
   182 
       
   183     Q_D( RadioUiEngine );
       
   184     if ( d->mPowerOffTimer ) {
       
   185         d->mPowerOffTimer->stop();
       
   186         d->mPowerOffTimer->deleteLater();
       
   187         d->mPowerOffTimer = NULL;
       
   188     }
       
   189 }
       
   190 
       
   191 /*!
       
   192  *
       
   193  */
       
   194 void RadioUiEngine::setPowerOff( int delay )
       
   195 {
       
   196     Q_D( RadioUiEngine );
       
   197     d->mEngineWrapper->setMute( true, false );
       
   198 
       
   199     if ( delay > 0 ) {
       
   200         if ( !d->mPowerOffTimer ) {
       
   201             d->mPowerOffTimer = new QTimer( this );
       
   202             Radio::connect( d->mPowerOffTimer,  SIGNAL(timeout()),
       
   203                             this,               SIGNAL(powerOffRequested()) );
       
   204         }
       
   205 
       
   206         d->mPowerOffTimer->start( delay );
       
   207     } else {
       
   208         emit powerOffRequested();
       
   209     }
       
   210 }
       
   211 
       
   212 /*!
       
   213  *
       
   214  */
       
   215 bool RadioUiEngine::isPoweringOff() const
       
   216 {
       
   217     Q_D( const RadioUiEngine );
       
   218     return d->mPowerOffTimer && d->mPowerOffTimer->isActive();
       
   219 }
       
   220 
       
   221 /*!
       
   222  * Returns the settings handler owned by the engine
       
   223  */
       
   224 RadioSettingsIf& RadioUiEngine::settings()
       
   225 {
       
   226     Q_D( RadioUiEngine );
       
   227     return d->mEngineWrapper->settings();
       
   228 }
       
   229 
       
   230 /*!
       
   231  * Returns the station model
       
   232  */
       
   233 RadioStationModel& RadioUiEngine::stationModel()
       
   234 {
       
   235     Q_D( RadioUiEngine );
       
   236     return *d->mStationModel;
       
   237 }
       
   238 
       
   239 /*!
       
   240  * Returns the history model
       
   241  */
       
   242 RadioHistoryModel& RadioUiEngine::historyModel()
       
   243 {
       
   244     Q_D( RadioUiEngine );
       
   245     return *d->mHistoryModel;
       
   246 }
       
   247 
       
   248 /*!
       
   249  * Creates a scanner engine and returns a pointer to it
       
   250  * The returned pointer is wrapped inside a QScopedPointer to ensure this won't
       
   251  * leak memory. The returned engine will be deleted even if the caller ignored
       
   252  * the return value.
       
   253  */
       
   254 RadioScannerEnginePtr RadioUiEngine::createScannerEngine()
       
   255 {
       
   256     Q_D( RadioUiEngine );
       
   257 #if defined BUILD_WIN32 || defined __WINS__
       
   258     Q_ASSERT_X( !d->mScannerEngine, "RadioUiEngine::createScannerEngine", "Previous scanner instance not freed" );
       
   259 #endif
       
   260 
       
   261     RadioScannerEnginePtr enginePtr( new RadioScannerEngine( *d ) );
       
   262     d->mScannerEngine = enginePtr;
       
   263 
       
   264     return enginePtr;
       
   265 }
       
   266 
       
   267 /*!
       
   268  *
       
   269  */
       
   270 RadioScannerEngine* RadioUiEngine::scannerEngine()
       
   271 {
       
   272     Q_D( RadioUiEngine );
       
   273     return d->mScannerEngine.data();
       
   274 }
       
   275 
       
   276 /*!
       
   277  *
       
   278  */
       
   279 bool RadioUiEngine::isRadioOn() const
       
   280 {
       
   281     Q_D( const RadioUiEngine );
       
   282     return d->mEngineWrapper->isRadioOn();
       
   283 }
       
   284 
       
   285 /*!
       
   286  *
       
   287  */
       
   288 bool RadioUiEngine::isScanning() const
       
   289 {
       
   290     Q_D( const RadioUiEngine );
       
   291     if ( d->mScannerEngine ) {
       
   292         return d->mScannerEngine.data()->isScanning();
       
   293     }
       
   294     return false;
       
   295 }
       
   296 
       
   297 /*!
       
   298  *
       
   299  */
       
   300 bool RadioUiEngine::isMuted() const
       
   301 {
       
   302     Q_D( const RadioUiEngine );
       
   303     return d->mEngineWrapper->isMuted();
       
   304 }
       
   305 
       
   306 /*!
       
   307  *
       
   308  */
       
   309 bool RadioUiEngine::isAntennaAttached() const
       
   310 {
       
   311     Q_D( const RadioUiEngine );
       
   312     return d->mEngineWrapper->isAntennaAttached();
       
   313 }
       
   314 
       
   315 /*!
       
   316  *
       
   317  */
       
   318 bool RadioUiEngine::isUsingLoudspeaker() const
       
   319 {
       
   320     Q_D( const RadioUiEngine );
       
   321     return d->mEngineWrapper->isUsingLoudspeaker();
       
   322 }
       
   323 
       
   324 /*!
       
   325  * Returns the selected radio region
       
   326  */
       
   327 RadioRegion::Region RadioUiEngine::region() const
       
   328 {
       
   329     Q_D( const RadioUiEngine );
       
   330     return d->mEngineWrapper->region();
       
   331 }
       
   332 
       
   333 /*!
       
   334  * Returns the currently tuned frequency
       
   335  */
       
   336 uint RadioUiEngine::currentFrequency() const
       
   337 {
       
   338     Q_D( const RadioUiEngine );
       
   339     return d->mEngineWrapper->currentFrequency();
       
   340 }
       
   341 
       
   342 /*!
       
   343  * Returns the minimum frequency
       
   344  */
       
   345 uint RadioUiEngine::minFrequency() const
       
   346 {
       
   347     Q_D( const RadioUiEngine );
       
   348     return d->mEngineWrapper->minFrequency();
       
   349 }
       
   350 
       
   351 /*!
       
   352  * Returns the maximum frequency
       
   353  */
       
   354 uint RadioUiEngine::maxFrequency() const
       
   355 {
       
   356     Q_D( const RadioUiEngine );
       
   357     return d->mEngineWrapper->maxFrequency();
       
   358 }
       
   359 
       
   360 /*!
       
   361  * Returns the frequency step size from the selected region
       
   362  */
       
   363 uint RadioUiEngine::frequencyStepSize() const
       
   364 {
       
   365     Q_D( const RadioUiEngine );
       
   366     return d->mEngineWrapper->frequencyStepSize();
       
   367 }
       
   368 
       
   369 /*!
       
   370  * Sets the mute status
       
   371  */
       
   372 void RadioUiEngine::setMute( bool muted )
       
   373 {
       
   374     Q_D( RadioUiEngine );
       
   375     d->mEngineWrapper->setMute( muted );
       
   376 }
       
   377 
       
   378 /*!
       
   379  *
       
   380  */
       
   381 QList<RadioStation> RadioUiEngine::stationsInRange( uint minFrequency, uint maxFrequency )
       
   382 {
       
   383     Q_D( RadioUiEngine );
       
   384     return d->mStationModel->stationsInRange( minFrequency, maxFrequency );
       
   385 }
       
   386 
       
   387 /*!
       
   388  *
       
   389  */
       
   390 QString RadioUiEngine::genreToString( int genre, GenreTarget::Target target )
       
   391 {
       
   392     return RadioGenreLocalizer::genreToString( region(), genre, target );
       
   393 }
       
   394 
       
   395 /*!
       
   396  *
       
   397  */
       
   398 bool RadioUiEngine::isSongRecognitionAppAvailable()
       
   399 {
       
   400     //TODO: Implement Shazam support
       
   401     return false;
       
   402 }
       
   403 
       
   404 /*!
       
   405  *
       
   406  */
       
   407 void RadioUiEngine::addRecognizedSong( const QString& artist, const QString& title, const RadioStation& station )
       
   408 {
       
   409     Q_D( RadioUiEngine );
       
   410     d->mHistoryModel->addItem( artist, title, station );
       
   411 }
       
   412 
       
   413 /*!
       
   414  *
       
   415  */
       
   416 uint RadioUiEngine::skipStation( StationSkip::Mode mode, uint startFrequency, const int reason )
       
   417 {
       
   418     Q_D( RadioUiEngine );
       
   419     return d->skip( mode, startFrequency, reason );
       
   420 }
       
   421 
       
   422 /*!
       
   423  *
       
   424  */
       
   425 void RadioUiEngine::openMusicStore( const RadioHistoryItem& item, MusicStore store )
       
   426 {
       
   427     QString artist = item.artist();
       
   428     artist.replace( WHITESPACE, WHITESPACE_REPLACEMENT );
       
   429     QString title = item.title();
       
   430     title.replace( WHITESPACE, WHITESPACE_REPLACEMENT );
       
   431 
       
   432     QString url = store == OviStore ? OVI_STORE_URL : OTHER_STORE_URL;
       
   433     url.replace( OTHER_STORE_ARTIST_TAG, artist );
       
   434     url.replace( OTHER_STORE_TITLE_TAG, title );
       
   435 
       
   436     launchBrowser( url );
       
   437 }
       
   438 
       
   439 /*!
       
   440  *
       
   441  */
       
   442 void RadioUiEngine::launchBrowser( const QString& url )
       
   443 {
       
   444     QDesktopServices::openUrl( QUrl( url ) );
       
   445 }
       
   446 
       
   447 /*!
       
   448  * Sets or unsets the engine to manual seek mode
       
   449  */
       
   450 void RadioUiEngine::setManualSeekMode( bool manualSeek )
       
   451 {
       
   452     Q_D( RadioUiEngine );
       
   453     d->mEngineWrapper->setManualSeekMode( manualSeek );
       
   454 }
       
   455 
       
   456 /*!
       
   457  * Checks if the engine is in manual seek mode
       
   458  */
       
   459 bool RadioUiEngine::isInManualSeekMode() const
       
   460 {
       
   461     Q_D( const RadioUiEngine );
       
   462     return d->mEngineWrapper->isInManualSeekMode();
       
   463 }
       
   464 
       
   465 /*!
       
   466  * Tunes the radio engine to given frequency
       
   467  */
       
   468 void RadioUiEngine::setFrequency( uint frequency, const int reason )
       
   469 {
       
   470     Q_D( RadioUiEngine );
       
   471     if ( frequency != d->mStationModel->currentStation().frequency() && d->mEngineWrapper->isFrequencyValid( frequency ) ) {
       
   472         LOG_FORMAT( "RadioUiEngine::tuneFrequency, frequency: %d", frequency );
       
   473         d->cancelSeeking();
       
   474         d->mEngineWrapper->setFrequency( frequency, reason );
       
   475     }
       
   476 }
       
   477 
       
   478 /*!
       
   479  * Public slot
       
   480  * volume update command slot for the engine
       
   481  */
       
   482 void RadioUiEngine::setVolume( int volume )
       
   483 {
       
   484     Q_D( RadioUiEngine );
       
   485     d->mEngineWrapper->setVolume( volume );
       
   486 }
       
   487 
       
   488 /*!
       
   489  * Public slot
       
   490  *
       
   491  */
       
   492 void RadioUiEngine::toggleMute()
       
   493 {
       
   494     Q_D( RadioUiEngine );
       
   495     if ( !isScanning() ) {
       
   496         d->mEngineWrapper->setMute( !d->mEngineWrapper->isMuted() );
       
   497     }
       
   498 }
       
   499 
       
   500 /*!
       
   501  * Public slot
       
   502  *
       
   503  */
       
   504 void RadioUiEngine::toggleAudioRoute()
       
   505 {
       
   506     Q_D( RadioUiEngine );
       
   507     d->mEngineWrapper->toggleAudioRoute();
       
   508 }
       
   509 
       
   510 /*!
       
   511  * Public slot
       
   512  *
       
   513  */
       
   514 void RadioUiEngine::seekStation( int seekDirection )
       
   515 {
       
   516     if ( isAntennaAttached() ) {
       
   517         Q_D( RadioUiEngine );
       
   518         Seek::Direction direction = static_cast<Seek::Direction>( seekDirection );
       
   519         emitSeekingStarted( direction );
       
   520         d->mEngineWrapper->startSeeking( direction, TuneReason::Seek );
       
   521     }
       
   522 }
       
   523 
       
   524 /*!
       
   525  * Public slot
       
   526  *
       
   527  */
       
   528 void RadioUiEngine::launchSongRecognition()
       
   529 {
       
   530     //TODO: Implement Shazam support
       
   531 }
       
   532 
       
   533 /*!
       
   534  * Function used by the private implementation to emit a tunedToFrequency signal
       
   535  */
       
   536 void RadioUiEngine::emitTunedToFrequency( uint frequency, int commandSender )
       
   537 {
       
   538     emit tunedToFrequency( frequency, commandSender );
       
   539 }
       
   540 
       
   541 /*!
       
   542  * Function used by the private implementation to emit a seekingStarted signal
       
   543  */
       
   544 void RadioUiEngine::emitSeekingStarted( Seek::Direction direction )
       
   545 {
       
   546     emit seekingStarted( direction );
       
   547 }
       
   548 
       
   549 /*!
       
   550  * Function used by the private implementation to emit a radioStatusChanged signal
       
   551  */
       
   552 void RadioUiEngine::emitRadioStatusChanged( bool radioIsOn )
       
   553 {
       
   554     emit radioStatusChanged( radioIsOn );
       
   555 }
       
   556 
       
   557 /*!
       
   558  * Function used by the private implementation to emit a rdsAvailabilityChanged signal
       
   559  */
       
   560 void RadioUiEngine::emitRdsAvailabilityChanged( bool available )
       
   561 {
       
   562     emit rdsAvailabilityChanged( available );
       
   563 }
       
   564 
       
   565 /*!
       
   566  * Function used by the private implementation to emit a volumeChanged signal
       
   567  */
       
   568 void RadioUiEngine::emitVolumeChanged( int volume )
       
   569 {
       
   570     emit volumeChanged( volume );
       
   571 }
       
   572 
       
   573 /*!
       
   574  * Function used by the private implementation to emit a muteChanged signal
       
   575  */
       
   576 void RadioUiEngine::emitMuteChanged( bool muted )
       
   577 {
       
   578     emit muteChanged( muted );
       
   579 }
       
   580 
       
   581 /*!
       
   582  * Function used by the private implementation to emit a audioRouteChanged signal
       
   583  */
       
   584 void RadioUiEngine::emitAudioRouteChanged( bool loudspeaker )
       
   585 {
       
   586     emit audioRouteChanged( loudspeaker );
       
   587 }
       
   588 
       
   589 /*!
       
   590  * Function used by the private implementation to emit a antennaStatusChanged signal
       
   591  */
       
   592 void RadioUiEngine::emitAntennaStatusChanged( bool connected )
       
   593 {
       
   594     emit antennaStatusChanged( connected );
       
   595 }
       
   596