locationsystemui/locationsysui/locsettingsuiservice/locsettingsuiserver/src/locsettingsuilaunchao.cpp
branchRCL_3
changeset 44 2b4ea9893b66
parent 42 02ba3f1733c6
child 45 6b6920c56e2f
equal deleted inserted replaced
42:02ba3f1733c6 44:2b4ea9893b66
     1 /*
       
     2 * Copyright (c) 2005-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:  The implementation of Launch Active Object class of Location 
       
    15 *                Settings UI Server
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <aknViewAppUi.h>
       
    21 
       
    22 #include "locsettingsuilaunchao.h"
       
    23 #include "locsysuiengine.h"
       
    24 #include "locsettingsuisrvappui.h"
       
    25 #include "locsettingsuisrvdocument.h"
       
    26 #include "locationui.h"
       
    27 #include "locsettingsuiserverinterface.h"
       
    28 
       
    29 // ======== MEMBER FUNCTIONS ========
       
    30 
       
    31 // ---------------------------------------------------------------------------
       
    32 // CLocSettingsUISrvLaunchAO::NewL()
       
    33 // ---------------------------------------------------------------------------
       
    34 //
       
    35 CLocSettingsUISrvLaunchAO* CLocSettingsUISrvLaunchAO::NewL()
       
    36     {
       
    37     CLocSettingsUISrvLaunchAO* self = NewLC();
       
    38     CleanupStack::Pop(self);
       
    39     return self;    
       
    40     }
       
    41 
       
    42 
       
    43 // ---------------------------------------------------------------------------
       
    44 // CLocSettingsUISrvLaunchAO::NewLC()
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 CLocSettingsUISrvLaunchAO* CLocSettingsUISrvLaunchAO::NewLC()
       
    48     {
       
    49     CLocSettingsUISrvLaunchAO* self = new(ELeave) CLocSettingsUISrvLaunchAO;
       
    50     CleanupStack::PushL(self);
       
    51     self->ConstructL();
       
    52     return self;    
       
    53     }
       
    54 
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // CLocSettingsUISrvLaunchAO::~CLocSettingsUISrvLaunchAO()
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 CLocSettingsUISrvLaunchAO::~CLocSettingsUISrvLaunchAO()
       
    61     {
       
    62     // Deque request queue and send KErrServerTerminated Message for every
       
    63     // request.
       
    64     TSglQueIter<CLocSettingsUIInfo> iter(iRequestQue);
       
    65     CLocSettingsUIInfo* tmp = iter++;
       
    66     while( tmp )
       
    67         {
       
    68         // Complete each message with KErrServerTerminated
       
    69         // deque and delete them.
       
    70         CompleteRequest(tmp, KErrServerTerminated);
       
    71         tmp = iter++;
       
    72         }
       
    73     // The Engine reference will be deleted in the document class destructor
       
    74     // and should not be deleted here.
       
    75     }
       
    76 
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // CLocSettingsUISrvLaunchAO::EnqueueRequest( CLocSettingsUIInfo& aReqInfo )
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 void CLocSettingsUISrvLaunchAO::EnqueueRequest( CLocSettingsUIInfo* aReqInfo )
       
    83     {
       
    84     // Enque the request and set the active object to active state if
       
    85     // it is already not active.
       
    86     TBool listWasEmpty = iRequestQue.IsEmpty();
       
    87     iRequestQue.AddLast(*aReqInfo);
       
    88     // If this is the first request in the queue then trigger the Active Object
       
    89     // to Run. This is the only scenario where we want to trigger the 
       
    90     // Active Object from this method. In all other cases we will trigger the
       
    91     // Run from the Cancel method or the SettingsClosed method.
       
    92     if ( listWasEmpty && !IsActive() )
       
    93         {
       
    94         ScheduleAORun();
       
    95         // Bring the Application UI to foreground.
       
    96         BringAppToForeground();
       
    97         }
       
    98     }
       
    99 
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // CLocSettingsUISrvLaunchAO::CancelRequest( const CSession2* aSession )
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 void CLocSettingsUISrvLaunchAO::CancelRequest( const CSession2* aSession )
       
   106     {
       
   107     // Sanity Check the Request Queue
       
   108     if (iRequestQue.IsEmpty())
       
   109         {
       
   110         // Nothing to do if the request queue is empty.
       
   111         return;
       
   112         }
       
   113     // There are 2 cases here
       
   114     // 1. The Settings UI is currently running. In this case this Active 
       
   115     //    Object's cancel needs to be called and then the request needs
       
   116     //    to be dequeued in RunL when KErrCancel is obtained.
       
   117     // 2. The Settings UI is enqueued in the Request Queue. Here the 
       
   118     //    request needs to be dequeued and just responded with KErrCancel.
       
   119     CLocSettingsUIInfo* req = iRequestQue.First();
       
   120     if (req->Session() == aSession)
       
   121         {
       
   122         // Found the Settings UI and it is currently running.
       
   123         // Call Cancel. The request will be dequeued once the Cancel
       
   124         // Synchronous call is completed.
       
   125         // The RunL is usaually completed by the time the cancel comes. So the
       
   126         // Active Object is not necessarily Active. hence the call to Cancel
       
   127         // will fail. Instead we can directly call the DoCancel here.
       
   128         DoCancel();
       
   129         // In case there are more requests in the queue set this Active Object
       
   130         // to active state so that the next request will be processed.
       
   131         if (!iRequestQue.IsEmpty())
       
   132             {
       
   133             ScheduleAORun();
       
   134             }
       
   135         else
       
   136             {
       
   137             // Since there are no more requests to process let us go into
       
   138             // background. We won't wait till the client sessions are closed
       
   139             // because sometimes the client might have a UI response mechanism
       
   140             // or might even keep the session object till the end.
       
   141             SendAppToBackground();
       
   142             }
       
   143         }
       
   144     else
       
   145         {
       
   146         // Search the whole Queue.
       
   147         TSglQueIter<CLocSettingsUIInfo> iter(iRequestQue);
       
   148         CLocSettingsUIInfo* tmp = iter++;
       
   149         while( tmp )
       
   150             {
       
   151             if (tmp->Session() == aSession)
       
   152                 {
       
   153                 // Found the Settings UI. Complete the message with
       
   154                 // KErrCancel and deque this from the Queue.
       
   155                 CompleteRequest(tmp, KErrCancel);
       
   156                 break;
       
   157                 }
       
   158             tmp = iter++;
       
   159             }
       
   160         }
       
   161     return;
       
   162     }
       
   163 
       
   164 
       
   165 // ---------------------------------------------------------------------------
       
   166 // CLocSettingsUISrvLaunchAO::IsSrvRunningAsEmbeddedApp()
       
   167 // ---------------------------------------------------------------------------
       
   168 //
       
   169 TBool CLocSettingsUISrvLaunchAO::IsSrvRunningAsEmbeddedApp() const
       
   170     {
       
   171     return iIsSrvRunningAsEmbeddedApp;
       
   172     }
       
   173 
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 // From Base class MLocationUIObserver
       
   177 // CLocSettingsUISrvLaunchAO::LocationUIDismissed(TInt aErrorCode)
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 void CLocSettingsUISrvLaunchAO::LocationUIDismissed( TInt aErrorCode )
       
   181     {
       
   182     CLocSettingsUIInfo* req = iRequestQue.First();
       
   183     CompleteRequest(req, aErrorCode);
       
   184     
       
   185     // The request has been completed. Hence, assign it to NULL
       
   186     iLocationUI = NULL;
       
   187     
       
   188     //Check if more requests are queued.
       
   189     if ( !iRequestQue.IsEmpty() )
       
   190         {
       
   191         // Set this Active Object to Active State, so that the next request
       
   192         // will be processed in the RunL.
       
   193         ScheduleAORun();
       
   194         }
       
   195     else
       
   196         {
       
   197         // Since there are no more requests to process let us go into
       
   198         // background. We won't wait till the client sessions are closed
       
   199         // because sometimes the client might have a UI response mechanism
       
   200         // or might even keep the session object till the end.
       
   201         SendAppToBackground();
       
   202         }
       
   203     }
       
   204 
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // From Base class CActive
       
   208 // CLocSettingsUISrvLaunchAO::RunL()
       
   209 // 
       
   210 // Once the first request gets queued we get to this RunL execution.
       
   211 // ---------------------------------------------------------------------------
       
   212 //
       
   213 void CLocSettingsUISrvLaunchAO::RunL()
       
   214     {
       
   215     if ( !iEngine )
       
   216         {
       
   217         // The Engine is created here and then ownership is passed to the
       
   218         // Document class. There are 2 reasons for this,
       
   219         // 1. The Engine needs to be created late because it takes a AppUi
       
   220         //    parameter. Hence it has to be delayed till the AppUi is
       
   221         //    created. Also this class needs to add itself as the Observer
       
   222         //    for the Engine. hence this place is logically correct to
       
   223         //    create the Engine class.
       
   224         //
       
   225         // 2. The Engine class destruction needs to be delayed till the AppUi
       
   226         //    is destructed since the CAknViewAppUi calls view deactivate at
       
   227         //    that stage. When the CLocSysUiEngine is deleted then it frees all
       
   228         //    the ECOM implementation as well. So for view based plugins the
       
   229         //    AppUi deactivate after Engine destruction will cause a 
       
   230         //    KERN-EXEC 3. Hence we delay the destruction to the Document class
       
   231         //    destructor.
       
   232         // But still we maintain a local reference in this Launch class so that
       
   233         // we don't need to access the document class everytime which result
       
   234         // in a call to CEikonEnv::Static().
       
   235         CLocSettingsUISrvAppUi* appUi = 
       
   236                         static_cast<CLocSettingsUISrvAppUi*>
       
   237                         (iEikEnv->EikAppUi());
       
   238         
       
   239         CLocSettingsUISrvDoc* doc =                         
       
   240                     static_cast<CLocSettingsUISrvDoc*>
       
   241                     (const_cast<CEikDocument*>(appUi->Document()));
       
   242         
       
   243         iEngine = CLocSysUiEngine::NewL(*appUi);
       
   244         // HandOver the Engine Ownership to the Document class.
       
   245         doc->SetEngineInstance(iEngine);
       
   246         }
       
   247 
       
   248     // Sanity check that there is atleast one request.
       
   249     if ( !iRequestQue.IsEmpty() )
       
   250         {
       
   251         CLocSettingsUIInfo* req = iRequestQue.First();
       
   252         
       
   253         // Create the Location UI corresponding to the Location Request
       
   254         switch( req->IPCMessage().Function())
       
   255             {
       
   256             case ELaunchSettingsWithString:
       
   257                 {
       
   258                 TRAPD(error, iLocationUI = iEngine->CreateLocationSubSettingsUIL(req->SettingsUID()););
       
   259                 // TRAP and check whether the error is KErrAlreadyExists.
       
   260                 // In this case we don't need to leave. For all other
       
   261                 // error cases we leave here which will reuslt in the RunError
       
   262                 // getting executed with the error code.
       
   263                 if ( error != KErrNone && error != KErrAlreadyExists )
       
   264                     {
       
   265                     User::Leave(error);
       
   266                     }
       
   267                     
       
   268                 // Set Full Screen App
       
   269                 CLocSettingsUISrvAppUi* appUi = static_cast<CLocSettingsUISrvAppUi *>( iEikEnv->AppUi());
       
   270                 appUi->SetFullScreenState( ETrue );
       
   271                 
       
   272                 // Launch the Location UI
       
   273                 iLocationUI->LaunchLocationUIL( req->SettingsUIStringParamsL(),
       
   274                                                 this );             
       
   275                 break;
       
   276                 }
       
   277             case ELaunchSettings:
       
   278                 {
       
   279                 TRAPD(error, iLocationUI = iEngine->CreateLocationSubSettingsUIL(req->SettingsUID()););
       
   280                 // TRAP and check whether the error is KErrAlreadyExists.
       
   281                 // In this case we don't need to leave. For all other
       
   282                 // error cases we leave here which will reuslt in the RunError
       
   283                 // getting executed with the error code.
       
   284                 if ( error != KErrNone && error != KErrAlreadyExists )
       
   285                     {
       
   286                     User::Leave(error);
       
   287                     }
       
   288                     
       
   289                 // Set Full Screen App
       
   290                 CLocSettingsUISrvAppUi* appUi = static_cast<CLocSettingsUISrvAppUi *>( iEikEnv->AppUi());
       
   291                 appUi->SetFullScreenState( ETrue );
       
   292                 
       
   293                 // Launch the Location UI
       
   294                 iLocationUI->LaunchLocationUIL( req->SettingsUIIntParams(),
       
   295                                                 this );                
       
   296                 break;
       
   297                 }
       
   298             case ELaunchPosSettings:
       
   299                 {
       
   300                   TRAPD(error, iLocationUI = iEngine->CreatePositioningSettingsUIL(););
       
   301                 // TRAP and check whether the error is KErrAlreadyExists.
       
   302                 // In this case we don't need to leave. For all other
       
   303                 // error cases we leave here which will reuslt in the RunError
       
   304                 // getting executed with the error code.
       
   305                 if ( error != KErrNone )
       
   306                     {
       
   307                     User::Leave(error);
       
   308                     }
       
   309                     
       
   310                 // Set Full Screen App
       
   311                 CLocSettingsUISrvAppUi* appUi = static_cast<CLocSettingsUISrvAppUi *>( iEikEnv->AppUi());
       
   312                 appUi->SetFullScreenState( ETrue );
       
   313                                     
       
   314                 // Launch the Location UI
       
   315                 iLocationUI->LaunchLocationUIL( 0, this );
       
   316                 break;               
       
   317                 }
       
   318             default:
       
   319                 {
       
   320                 User::Leave( KErrNotSupported );
       
   321                 break;
       
   322                 }
       
   323             }
       
   324         }
       
   325     }
       
   326 
       
   327 
       
   328 // ---------------------------------------------------------------------------
       
   329 // From Base class CActive
       
   330 // CLocSettingsUISrvLaunchAO::DoCancel()
       
   331 // 
       
   332 // Once the first request gets queued we get to this RunL execution.
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 void CLocSettingsUISrvLaunchAO::DoCancel()
       
   336     {
       
   337     // Set Full Screen App
       
   338     CLocSettingsUISrvAppUi* appUi = static_cast<CLocSettingsUISrvAppUi *>( iEikEnv->AppUi());
       
   339     appUi->SetFullScreenState( EFalse );
       
   340                     
       
   341         
       
   342     // Call the LocSysUiEngine Interface to Cancel the launched Settings UI
       
   343     CLocSettingsUIInfo* req = iRequestQue.First();
       
   344     // The Location UI Close is a synchronous call.
       
   345     iLocationUI->Close();
       
   346     
       
   347     // The UI request has been cancelled. Hence, setting the value to NULL
       
   348     iLocationUI = NULL;
       
   349         
       
   350     // Deque the request and respond with the Error Code KErrCancel.
       
   351     CompleteRequest(req, KErrCancel);
       
   352     }
       
   353 
       
   354 
       
   355 // ---------------------------------------------------------------------------
       
   356 // From Base class CActive
       
   357 // CLocSettingsUISrvLaunchAO::RunError(TInt aError)
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 TInt CLocSettingsUISrvLaunchAO::RunError(TInt aError)
       
   361     {
       
   362     // Set Full Screen App
       
   363     CLocSettingsUISrvAppUi* appUi = static_cast<CLocSettingsUISrvAppUi *>( iEikEnv->AppUi());
       
   364     appUi->SetFullScreenState( EFalse );                   
       
   365                         
       
   366     // No specific error scenario seen as of now. So doing the logical thing.
       
   367     // Just complete the current reuqest with the returned error code.
       
   368     CLocSettingsUIInfo* req = iRequestQue.First();
       
   369     CompleteRequest(req, aError);
       
   370     //Check if more requests are queued.
       
   371     if (!iRequestQue.IsEmpty())
       
   372         {
       
   373         // Set this Active Object to Active State, so that the next request
       
   374         // will be processed in the RunL.
       
   375         ScheduleAORun();
       
   376         }
       
   377     else
       
   378         {
       
   379         // Since there are no more requests to process let us go into
       
   380         // background. We won't wait till the client sessions are closed
       
   381         // because sometimes the client might have a UI response mechanism
       
   382         // or might even keep the session object till the end.
       
   383         SendAppToBackground();
       
   384         }
       
   385     return KErrNone;
       
   386     }    
       
   387     
       
   388 // ---------------------------------------------------------------------------
       
   389 // CLocSettingsUISrvLaunchAO::CLocSettingsUISrvLaunchAO()
       
   390 // ---------------------------------------------------------------------------
       
   391 //
       
   392 CLocSettingsUISrvLaunchAO::CLocSettingsUISrvLaunchAO()
       
   393     :CActive(EPriorityUserInput),
       
   394      iRequestQue(CLocSettingsUIInfo::QueLinkOffset())
       
   395     {
       
   396     iEikEnv = CEikonEnv::Static();
       
   397     iIsSrvRunningAsEmbeddedApp = iEikEnv->StartedAsServerApp();
       
   398     }
       
   399 
       
   400 
       
   401 // ---------------------------------------------------------------------------
       
   402 // CLocSettingsUISrvLaunchAO::ConstructL()
       
   403 // ---------------------------------------------------------------------------
       
   404 //
       
   405 void CLocSettingsUISrvLaunchAO::ConstructL()
       
   406     {
       
   407     CActiveScheduler::Add(this);
       
   408     }
       
   409 
       
   410 
       
   411 // ======== HELPER MEMBER FUNCTIONS ========
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // CLocSettingsUISrvLaunchAO::CompleteRequest( CLocSettingsUIInfo* aReq,
       
   415 //                                             TInt aErrorCode )
       
   416 // ---------------------------------------------------------------------------
       
   417 //
       
   418 void CLocSettingsUISrvLaunchAO::CompleteRequest( 
       
   419     CLocSettingsUIInfo* aReq,
       
   420     TInt aErrorCode )
       
   421     {
       
   422     // Set Full Screen App
       
   423     CLocSettingsUISrvAppUi* appUi = static_cast<CLocSettingsUISrvAppUi *>( iEikEnv->AppUi());
       
   424     appUi->SetFullScreenState( EFalse );
       
   425         
       
   426     // The UI request is completed. Hence, setting the value to NULL
       
   427     iLocationUI = NULL;
       
   428     
       
   429     // Sanity check the request queue.
       
   430     if ( !iRequestQue.IsEmpty() )
       
   431         {
       
   432         // If queue is not empty then the aReq is valid 
       
   433         // otherwise it is invalid
       
   434         aReq->Complete(aErrorCode);
       
   435         iRequestQue.Remove(*aReq);
       
   436         delete aReq;
       
   437         }
       
   438     }
       
   439 
       
   440 
       
   441 // ---------------------------------------------------------------------------
       
   442 // CLocSettingsUISrvLaunchAO::SendAppToBackground()
       
   443 // This is specifically needed when Location Server is running as standalone
       
   444 // and not embedded
       
   445 // ---------------------------------------------------------------------------
       
   446 //
       
   447 void CLocSettingsUISrvLaunchAO::SendAppToBackground()
       
   448     {
       
   449     if ( !IsSrvRunningAsEmbeddedApp() )
       
   450         {
       
   451         // Do this only if the server is running as standalone server.
       
   452         // In case of embedded server application, it will be closed 
       
   453         // immediately. Hence there is no need to take it to background.
       
   454         CAknAppUi* appUi = static_cast<CAknAppUi*>(iEikEnv->EikAppUi());
       
   455         // The last view cannot be destroyed till the server shutsdown.
       
   456         // Hence do a Hide from FSW here and move into background.
       
   457         // Once the shutdown timer is completed, the view will be destroyed.
       
   458         appUi->HideApplicationFromFSW(ETrue);
       
   459         if ( appUi->IsForeground() )
       
   460             {
       
   461             TApaTask task(iEikEnv->WsSession());
       
   462             task.SetWgId(iEikEnv->RootWin().Identifier());
       
   463             task.SendToBackground();
       
   464             }
       
   465         }
       
   466     }
       
   467 
       
   468 
       
   469 // ---------------------------------------------------------------------------
       
   470 // CLocSettingsUISrvLaunchAO::BringAppToForeground()
       
   471 // This is specifically needed when Location Server is running as standalone
       
   472 // and not embedded
       
   473 // ---------------------------------------------------------------------------
       
   474 //
       
   475 void CLocSettingsUISrvLaunchAO::BringAppToForeground()
       
   476     {
       
   477     if ( !IsSrvRunningAsEmbeddedApp() )
       
   478         {
       
   479         // Do this only if the server is running as standalone server.
       
   480         // In case of embedded server application, it will be closed 
       
   481         // immediately. Hence there is no need to bring it to foreground.
       
   482         CAknAppUi* appUi = static_cast<CAknAppUi*>(iEikEnv->EikAppUi());
       
   483         appUi->HideApplicationFromFSW(EFalse);
       
   484         TApaTask task(iEikEnv->WsSession());
       
   485         task.SetWgId(iEikEnv->RootWin().Identifier());
       
   486         task.BringToForeground();
       
   487         }
       
   488     }
       
   489 
       
   490 
       
   491 // ---------------------------------------------------------------------------
       
   492 // CLocSettingsUISrvLaunchAO::ScheduleAORun()
       
   493 // ---------------------------------------------------------------------------
       
   494 //
       
   495 void CLocSettingsUISrvLaunchAO::ScheduleAORun()
       
   496     {
       
   497     SetActive();
       
   498     TRequestStatus* status = &iStatus;
       
   499     // This is a dummy AO to drive the UI launch requests. hence it is okay to
       
   500     // complete the request with KErrNone since all we want is to get the RunL
       
   501     // called by the Active Scheduler.
       
   502     User::RequestComplete(status, KErrNone);
       
   503     }
       
   504     
       
   505     
       
   506 // End of file