homescreenapp/runtimeplugins/hsdefaultruntimeplugin/src/hsdefaultruntime.cpp
changeset 77 4b195f3bea29
parent 61 2b1b11a301d2
child 85 35368b604b28
equal deleted inserted replaced
61:2b1b11a301d2 77:4b195f3bea29
     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:  Default implementation of the home screen runtime.
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QState>
       
    19 #include <QFinalState>
       
    20 #include <QHistoryState>
       
    21 #include <QSignalTransition>
       
    22 #include <QKeyEventTransition>
       
    23 #include <QKeyEvent>
       
    24 
       
    25 #include <qvaluespacepublisher.h>
       
    26 #include <qservicemanager.h>
       
    27 #include <qservicefilter.h>
       
    28 #include <qserviceinterfacedescriptor.h>
       
    29 
       
    30 #include <HbApplication>
       
    31 #include <HbActivityManager>
       
    32 #include <HbInstance>
       
    33 #include <HbIconAnimationManager>
       
    34 #include <HbIconAnimationDefinition>
       
    35 
       
    36 #include "hsmenueventfactory.h"
       
    37 #include "homescreendomainpskeys.h"
       
    38 #include "hsdefaultruntime.h"
       
    39 #include "hsdatabase.h"
       
    40 #include "hscontentservice.h"
       
    41 #include "hsshortcutservice.h"
       
    42 #include "hsmenueventtransition.h"
       
    43 #include "hswidgetpositioningonorientationchange.h"
       
    44 #include "hswidgetpositioningonwidgetadd.h"
       
    45 #include "hsconfiguration.h"
       
    46 #include "hstest_global.h"
       
    47 #include "hswidgetpositioningonwidgetmove.h"
       
    48 
       
    49 QTM_USE_NAMESPACE
       
    50 #define hbApp qobject_cast<HbApplication*>(qApp)
       
    51 
       
    52 #ifdef Q_OS_SYMBIAN
       
    53 const static Qt::Key applicationKey = Qt::Key_Menu;
       
    54 #else
       
    55 const static Qt::Key applicationKey = Qt::Key_Home;
       
    56 #endif
       
    57 
       
    58 namespace
       
    59 {
       
    60     const char KHsRootStateInterface[] = "com.nokia.homescreen.state.HsRootState";
       
    61     const char KHsLoadSceneStateInterface[] = "com.nokia.homescreen.state.HsLoadSceneState";
       
    62     const char KHsIdleStateInterface[] = "com.nokia.homescreen.state.HsIdleState";
       
    63     const char KHsAppLibraryStateInterface[] = "com.nokia.homescreen.state.HsAppLibraryState";
       
    64     const char KHsMenuWorkerStateInterface[] = "com.nokia.homescreen.state.HsMenuWorkerState";
       
    65     const char KHsBacupRestoreStateInterface[] = "com.nokia.homescreen.state.HsBackupRestoreState";
       
    66 }
       
    67 
       
    68 
       
    69 /*!
       
    70     \class HsDefaultRuntime
       
    71     \ingroup group_hsdefaultruntimeplugin
       
    72     \brief Default implementation of the home screen runtime.
       
    73     Creates an execution context (EC) and populates it with
       
    74     runtime services. States are loaded from state plugins.
       
    75     Each state is given an access to the EC. States
       
    76     are added to a state machine. Finally, the state machine
       
    77     is started.
       
    78 */
       
    79 
       
    80 /*!
       
    81     Constructs runtime with \a parent as the parent object.
       
    82 */
       
    83 HsDefaultRuntime::HsDefaultRuntime(QObject *parent)
       
    84     : QStateMachine(parent),
       
    85       mContentService(0),	  
       
    86       mHomeScreenActive(false),
       
    87       mIdleStateActive(false),
       
    88       mPublisher(NULL)
       
    89 #ifdef Q_OS_SYMBIAN
       
    90 	  ,keyCapture()
       
    91 #endif
       
    92 {
       
    93     HSTEST_FUNC_ENTRY("HS::HsDefaultRuntime::HsDefaultRuntime");
       
    94 
       
    95     HsDatabase *db = new HsDatabase;
       
    96     db->setConnectionName("homescreen.dbc");
       
    97 #ifdef Q_OS_SYMBIAN
       
    98     db->setDatabaseName("c:/private/20022f35/homescreen.db");
       
    99 #else
       
   100     db->setDatabaseName("private/20022f35/homescreen.db");
       
   101 #endif    
       
   102     db->open();
       
   103     HsDatabase::setInstance(db);
       
   104 
       
   105     HsConfiguration::setInstance(new HsConfiguration);
       
   106     HsConfiguration::instance()->load();
       
   107             
       
   108     HsWidgetPositioningOnOrientationChange::setInstance(
       
   109         new HsAdvancedWidgetPositioningOnOrientationChange);
       
   110 
       
   111     HsWidgetPositioningOnWidgetAdd::setInstance(
       
   112         new HsAnchorPointInBottomRight);
       
   113 
       
   114     HsWidgetPositioningOnWidgetMove::setInstance(
       
   115         new HsSnapToLines);
       
   116 
       
   117     registerAnimations();
       
   118 
       
   119     createStatePublisher();
       
   120     createContentServiceParts();
       
   121     createStates();
       
   122     assignServices();
       
   123 
       
   124     // create the instance so that singleton is accessible from elsewhere
       
   125     HsShortcutService::instance(this);
       
   126 
       
   127     QCoreApplication::instance()->installEventFilter(this);
       
   128 
       
   129     if (hbApp) { // Qt test framework uses QApplication.
       
   130         connect(hbApp->activityManager(), SIGNAL(activityRequested(QString)), 
       
   131                 this, SLOT(activityRequested(QString)));
       
   132     }
       
   133     HSTEST_FUNC_EXIT("HS::HsDefaultRuntime::HsDefaultRuntime");
       
   134 }
       
   135 
       
   136 /*!
       
   137     Destructor.
       
   138 */
       
   139 HsDefaultRuntime::~HsDefaultRuntime()
       
   140 {
       
   141     HsWidgetPositioningOnOrientationChange::setInstance(0);
       
   142     delete mPublisher;
       
   143 }
       
   144 
       
   145 /*!
       
   146     \fn void HsDefaultRuntime::stopStateMachine()
       
   147     Emission of this signal initiates a transition to the final state.
       
   148 */
       
   149 
       
   150 /*!
       
   151     \copydoc QObject::eventFilter(QObject *watched, QEvent *event)
       
   152 */
       
   153 bool HsDefaultRuntime::eventFilter(QObject *watched, QEvent *event)
       
   154 {
       
   155     Q_UNUSED(watched);
       
   156 
       
   157     switch (event->type()) {
       
   158         case QEvent::ApplicationActivate:
       
   159             qDebug() << "HsDefaultRuntime::eventFilter: QEvent::ApplicationActivate";
       
   160 #ifdef Q_OS_SYMBIAN
       
   161             keyCapture.captureKey(applicationKey);
       
   162 #endif
       
   163             mHomeScreenActive = true;
       
   164             updatePSKeys();
       
   165             break;
       
   166         case QEvent::ApplicationDeactivate:
       
   167             qDebug() << "HsDefaultRuntime::eventFilter: QEvent::ApplicationDeactivate";
       
   168 #ifdef Q_OS_SYMBIAN
       
   169             keyCapture.cancelCaptureKey(applicationKey);
       
   170 #endif
       
   171             mHomeScreenActive = false;
       
   172             updatePSKeys();
       
   173             break;
       
   174         default:
       
   175             break;
       
   176     }
       
   177    
       
   178     bool result =  QStateMachine::eventFilter(watched, event);
       
   179     // temporary hack as we should not register twice for events
       
   180     if (event->type() == QEvent::KeyPress ) {
       
   181         QKeyEvent* ke = static_cast<QKeyEvent *>(event);         
       
   182         // Key_Launch0 should be removed when QT starts to send Key_Menu
       
   183         result = (ke->key() == applicationKey) || ke->key() == Qt::Key_Launch0;        
       
   184     }
       
   185     return result;
       
   186 }
       
   187 
       
   188 
       
   189 /*!
       
   190     Registers framework animations.
       
   191 */
       
   192 void HsDefaultRuntime::registerAnimations()
       
   193 {
       
   194     HbIconAnimationManager *manager = HbIconAnimationManager::global();
       
   195     manager->addDefinitionFile(QLatin1String("qtg_anim_loading.axml"));
       
   196 }
       
   197 
       
   198 /*!
       
   199     Creates Home screen state publisher.
       
   200 */
       
   201 void HsDefaultRuntime::createStatePublisher()
       
   202 {
       
   203     mPublisher = new QValueSpacePublisher(QValueSpace::PermanentLayer, HsStatePSKeyPath);
       
   204 
       
   205     if (!mPublisher->isConnected()){
       
   206     	// No permanent layer available
       
   207     	mPublisher = new QValueSpacePublisher(HsStatePSKeyPath);
       
   208     }
       
   209 
       
   210     mPublisher->setValue(HsStatePSKeySubPath, EHomeScreenInactive);
       
   211 }
       
   212 
       
   213 /*!
       
   214     Creates content service parts.
       
   215 */
       
   216 void HsDefaultRuntime::createContentServiceParts()
       
   217 {
       
   218     HSTEST_FUNC_ENTRY("HS::HsDefaultRuntime::createContentServiceParts");
       
   219 
       
   220     mContentService = new HsContentService(this);
       
   221 
       
   222     HSTEST_FUNC_EXIT("HS::HsDefaultRuntime::createContentServiceParts");
       
   223 }
       
   224 
       
   225 /*!
       
   226     Creates states.
       
   227 */
       
   228 void HsDefaultRuntime::createStates()
       
   229 {
       
   230     HSTEST_FUNC_ENTRY("HS::HsDefaultRuntime::createStates");
       
   231 
       
   232     QFinalState *finalState = new QFinalState();
       
   233     addState(finalState);
       
   234 
       
   235     QState *guiRootState = new QState();
       
   236     addState(guiRootState);
       
   237 
       
   238     guiRootState->addTransition(this, SIGNAL(event_exit()), finalState);
       
   239 
       
   240     QServiceManager manager;
       
   241 
       
   242     
       
   243     QObject *loadSceneStateObj = manager.loadInterface(KHsLoadSceneStateInterface);
       
   244     QState *loadSceneState = qobject_cast<QState *>(loadSceneStateObj);
       
   245     loadSceneState->setParent(guiRootState);
       
   246     loadSceneState->setObjectName(KHsLoadSceneStateInterface);
       
   247 
       
   248     QObject *rootStateObj = manager.loadInterface(KHsRootStateInterface);
       
   249     QState *rootState = qobject_cast<QState *>(rootStateObj);   
       
   250     rootState->setParent(guiRootState);
       
   251     rootState->setObjectName(KHsRootStateInterface);       
       
   252 
       
   253     QObject *idleStateObj = manager.loadInterface(KHsIdleStateInterface);
       
   254     QState *idleState = qobject_cast<QState *>(idleStateObj);
       
   255     idleState->setParent(rootState);
       
   256     idleState->setObjectName(KHsIdleStateInterface);
       
   257 	connect(idleState, SIGNAL(entered()), SLOT(onIdleStateEntered()));
       
   258 	connect(idleState, SIGNAL(exited()), SLOT(onIdleStateExited()));
       
   259 
       
   260 
       
   261     //menu state
       
   262     QState *menuParallelState = new QState(
       
   263             QState::ParallelStates, rootState);
       
   264     QState *menuRootState = new QState(menuParallelState);
       
   265 
       
   266     QObject *appLibraryStateObj = manager.loadInterface(KHsAppLibraryStateInterface);
       
   267     QState *appLibraryState = qobject_cast<QState *>(appLibraryStateObj);
       
   268     appLibraryState->setParent(menuRootState);
       
   269     appLibraryState->setObjectName(KHsAppLibraryStateInterface);
       
   270     menuRootState->setInitialState(appLibraryState);
       
   271 
       
   272     QHistoryState *historyState = new QHistoryState(rootState);
       
   273     historyState->setDefaultState(idleState);
       
   274     
       
   275     loadSceneState->addTransition(
       
   276             loadSceneState, SIGNAL(event_history()), historyState);            
       
   277 
       
   278     QObject *menuWorkerStateObj = manager.loadInterface(KHsMenuWorkerStateInterface);
       
   279     QState *menuWorkerState = qobject_cast<QState *>(menuWorkerStateObj);
       
   280     menuWorkerState->setParent(menuParallelState);
       
   281     menuWorkerState->setObjectName(KHsMenuWorkerStateInterface);
       
   282 
       
   283     connect(appLibraryState, SIGNAL(collectionEntered()), 
       
   284             menuWorkerState, SIGNAL(reset()));
       
   285     connect(appLibraryState, SIGNAL(allAppsStateEntered ()), 
       
   286             menuWorkerState, SIGNAL(reset()));
       
   287     connect(appLibraryState, SIGNAL(allCollectionsStateEntered ()), 
       
   288             menuWorkerState, SIGNAL(reset()));
       
   289 
       
   290     //Backup/Restore state
       
   291     QObject *backupRestoreStateObj = manager.loadInterface(KHsBacupRestoreStateInterface);
       
   292     QState *backupRestoreState = qobject_cast<QState *>(backupRestoreStateObj);   
       
   293     backupRestoreState->setParent(guiRootState);
       
   294     backupRestoreState->setObjectName(KHsBacupRestoreStateInterface);
       
   295     backupRestoreState->addTransition(
       
   296             backupRestoreState, SIGNAL(event_loadScene()), loadSceneState);
       
   297 
       
   298     // root state transitions
       
   299     idleState->addTransition(idleState, SIGNAL(event_applicationLibrary()), menuRootState);
       
   300     appLibraryState->addTransition(
       
   301             appLibraryState, SIGNAL(toHomescreenState()), idleState);
       
   302     rootState->addTransition(rootState, SIGNAL(event_backupRestore()), backupRestoreState);
       
   303     // opening shortcut to Application Library
       
   304     HsMenuEventTransition *idleToAppLibTransition =
       
   305         new HsMenuEventTransition(HsMenuEvent::OpenApplicationLibrary,
       
   306                                   idleState, appLibraryState);
       
   307     idleState->addTransition(idleToAppLibTransition);
       
   308 
       
   309     HsMenuEventTransition *appLibToIdleTransition =
       
   310         new HsMenuEventTransition(
       
   311             HsMenuEvent::OpenHomeScreen, appLibraryState, idleState);
       
   312     appLibraryState->addTransition(appLibToIdleTransition);
       
   313 
       
   314     HbMainWindow *window = hbInstance->allMainWindows().first();
       
   315 
       
   316     // key driven transition from idle to menu
       
   317     QKeyEventTransition *idleToMenuRootTransition =
       
   318         new QKeyEventTransition(
       
   319                 window, QEvent::KeyPress, applicationKey);
       
   320     idleToMenuRootTransition->setTargetState(menuRootState);
       
   321     idleState->addTransition(idleToMenuRootTransition);
       
   322     // key driven transition from menu to idle
       
   323     QKeyEventTransition *menuToIdleTransition =
       
   324         new QKeyEventTransition(
       
   325                 window, QEvent::KeyPress, applicationKey);
       
   326     menuToIdleTransition->setTargetState(idleState);
       
   327     menuRootState->addTransition(menuToIdleTransition);
       
   328     
       
   329     // transition for Key_Launch0 should be removed 
       
   330     // when OT starts to send Key_Menu (maybe wk14)
       
   331     QKeyEventTransition *idleToMenuRootTransition2 =
       
   332         new QKeyEventTransition(
       
   333                 window, QEvent::KeyPress, Qt::Key_Launch0);
       
   334     idleToMenuRootTransition2->setTargetState(menuRootState);
       
   335     idleState->addTransition(idleToMenuRootTransition2);
       
   336     // key driven transition from menu to idle
       
   337     QKeyEventTransition *menuToIdleTransition2 =
       
   338         new QKeyEventTransition(
       
   339                 window, QEvent::KeyPress, Qt::Key_Launch0);
       
   340     menuToIdleTransition2->setTargetState(idleState);
       
   341     menuRootState->addTransition(menuToIdleTransition2);
       
   342     // add transition to switch to idle
       
   343     menuRootState->addTransition( this, SIGNAL(event_toIdle()), idleState);    
       
   344     
       
   345     // transitions to child states
       
   346     // opening shortcut to a colleciton
       
   347     QList<QState *> collectionStates =
       
   348         appLibraryState->
       
   349             findChildren<QState *>
       
   350                 ("homescreen.nokia.com/state/applibrarystate/collectionstate");
       
   351     qDebug(
       
   352         "Found %d \"collectionstate\" children for Application Library State",
       
   353             collectionStates.count());
       
   354     if (collectionStates.count()) {
       
   355         HsMenuEventTransition *idleToCollectionTransition =
       
   356             new HsMenuEventTransition(HsMenuEvent::OpenCollection,
       
   357                                       idleState, collectionStates[0]);
       
   358         idleState->addTransition(idleToCollectionTransition);
       
   359     }
       
   360 
       
   361     guiRootState->setInitialState(loadSceneState);
       
   362     setInitialState(guiRootState);
       
   363     
       
   364     HSTEST_FUNC_EXIT("HS::HsDefaultRuntime::createStates");
       
   365 }
       
   366 
       
   367 /*!
       
   368     Assigns services to states based on value of property HS_SERVICES_REGISTRATION_KEY.
       
   369 */
       
   370 void HsDefaultRuntime::assignServices()
       
   371 {
       
   372     HSTEST_FUNC_ENTRY("HS::HsDefaultRuntime::assignServices");
       
   373 
       
   374     QList<QState*> children = findChildren<QState*>();
       
   375     foreach (QState *state, children) {
       
   376         QList<QVariant> services = state->property(HS_SERVICES_REGISTRATION_KEY).toList();
       
   377         foreach (const QVariant &service, services) {
       
   378             QString name = service.toString();
       
   379             qDebug() << "Assign service:" << name << "\n to " << state->objectName();
       
   380             if (name == CONTENT_SERVICE_KEY) {
       
   381                 state->setProperty(name.toAscii().data(), qVariantFromValue(mContentService));
       
   382             } else if (name == SHORTCUT_SERVICE_KEY) {
       
   383                 state->setProperty(name.toAscii().data(),
       
   384                     qVariantFromValue(HsShortcutService::instance(this)));
       
   385             } else {
       
   386                 qWarning() << "WARNING: Service " << name << " is unknown";
       
   387             }
       
   388         }
       
   389     }
       
   390 
       
   391     HSTEST_FUNC_EXIT("HS::HsDefaultRuntime::assignServices");
       
   392 }
       
   393 
       
   394 /*!
       
   395     Publishes Home screen states via Publish & Subscribe.
       
   396 */
       
   397 void HsDefaultRuntime::updatePSKeys()
       
   398 {	
       
   399 	if (!mPublisher){
       
   400 		createStatePublisher();
       
   401 	}
       
   402 
       
   403 	if (mHomeScreenActive && mIdleStateActive){
       
   404     	qDebug() << "HsDefaultRuntime::updatePSKeys: EHomeScreenIdleState";
       
   405     	mPublisher->setValue(HsStatePSKeySubPath, EHomeScreenIdleState);
       
   406     }
       
   407     else{
       
   408     	qDebug() << "HsDefaultRuntime::updatePSKeys: EHomeScreenInactive";
       
   409     	mPublisher->setValue(HsStatePSKeySubPath, EHomeScreenInactive);
       
   410     }	
       
   411 }
       
   412 
       
   413 /*!
       
   414     Called when state machine is in Idle state.
       
   415 */
       
   416 void HsDefaultRuntime::onIdleStateEntered()
       
   417 {
       
   418 	mIdleStateActive = true;
       
   419 	updatePSKeys();
       
   420 }
       
   421 
       
   422 /*!
       
   423     Called when state machine leaves the Idle state.
       
   424 */
       
   425 void HsDefaultRuntime::onIdleStateExited()
       
   426 {
       
   427 	mIdleStateActive = false;
       
   428 	updatePSKeys();
       
   429 }
       
   430 
       
   431 /*!
       
   432     Activity requested by another client 
       
   433 */
       
   434 void HsDefaultRuntime::activityRequested(const QString &name) 
       
   435 {
       
   436     if (name == appLibActivity()) {
       
   437         this->postEvent(
       
   438             HsMenuEventFactory::createOpenAppLibraryEvent(NormalHsMenuMode));
       
   439     }
       
   440     else if (name == groupAppLibRecentView()) {
       
   441         this->postEvent(
       
   442             HsMenuEventFactory::createOpenCollectionEvent(0,
       
   443             collectionDownloadedTypeName()));
       
   444     } else if (name == activityHsIdleView()) {
       
   445         emit event_toIdle();
       
   446     }
       
   447 }