locationcentre/lcservice/src/lcserviceimpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 15 Mar 2010 12:40:01 +0200
branchRCL_3
changeset 9 91123d004e8f
parent 0 522cd55cc3d7
child 12 dcfab14f2c3a
permissions -rw-r--r--
Revision: 201009 Kit: 201010

/*
* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Location Centre API interface.
*
*/


// SYSTEM INCLUDES
#include <s32mem.h>
#include <aknsutils.h>
#include <gulicon.h>
#include <aknlists.h>
#include <aknPopup.h>
#include <avkon.rsg>

// USER INCLUDES
#include "lcserviceimpl.h"
#include "lclocationappfilter.h"
#include "lcappexitobserver.h"
#include "lcnotification.h"
#include "lcapplauncher.h"
#include "lcipcparams.h"
#include "lcnotificationao.h"
#include "lciconloader.h"
#include "lcsyncoperation.h"
#include "lcpopuplistbox.h"
#include "lcdebug.h"

// ----- Member funtions for CLcServiceImpl ---------------------------------

// ---------------------------------------------------------------------------
// CLcServiceImpl::CLcServiceImpl
// ---------------------------------------------------------------------------
//
CLcServiceImpl::CLcServiceImpl()
    {
    // C++ Default constructor. No allocations or functions which can Leave
    // should be called from here.
    }
         
// ---------------------------------------------------------------------------
// CLcServiceImpl::~CLcServiceImpl
// ---------------------------------------------------------------------------
//
CLcServiceImpl::~CLcServiceImpl()
    {
    // C++ Destructor. Free all resources associated with this class.
    if ( iPopUp )
        {
        iPopUp->CancelPopup();
        }
    
    // Delele the Pop-up list    
    delete iPopUpListBox;
    
    // Delete the Selected ID buffer   
    delete iSelectedAppId;
                
    // Delete filter parameters
    delete iFilter;
    
    // Delete the Application information array
    iAppArray.Reset();
    iAppArray.Close();

    // Delete the Notification Active object
    delete iNotificationAO;
    
    // Delete the Application launcher
    delete iAppLauncher;
    
    // If there is an outstanding request then complete the same with KErrCancel.
    if ( iAsyncOperation )
    	{
    	iAsyncOperation->CancelGetLocationApplications();
    	User::RequestComplete( iStatus, KErrCompletion );
    	
    	// We can now delete the asynchronous operation
    	delete iAsyncOperation;
    	iAsyncOperation = NULL;
    	} 
    	    
    // Close the session handle. The session handle is active throughout the
    // lifetime of this class
    iSession.Close();
    
    }
        
// ---------------------------------------------------------------------------
// CLcServiceImpl* CLcServiceImpl::NewL
// ---------------------------------------------------------------------------
//
CLcServiceImpl* CLcServiceImpl::NewL()
    {
    CLcServiceImpl* self = NewLC();
    CleanupStack::Pop( self );
    return self;         
    }

// ---------------------------------------------------------------------------
// CLcServiceImpl* CLcServiceImpl::NewLC
// ---------------------------------------------------------------------------
//
CLcServiceImpl* CLcServiceImpl::NewLC()
    {
    // Symbian Two phased constructor. Leaves the object on the Clean-up
    // stack.
    CLcServiceImpl* self = 
                new ( ELeave )CLcServiceImpl();
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;         
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::ConstructL
// ---------------------------------------------------------------------------
//
void CLcServiceImpl::ConstructL()
    {
    // Second phase of the two phase constructor.
    
    // Open a connection to the Location Centre Server
    // The connection is opened at the class construction and Closed at the
    // class deletion. This is done inorder to avoid delays during every
    // operation
    User::LeaveIfError( iSession.CreateSession());
    
    // Create the Location application launcher.
    iAppLauncher = CLcAppLauncher::NewL();
    
    // Create the Notification AO
    iNotificationAO = CLcNotificationAO::NewL( *this, iSession );
    }
                    
// ---------------------------------------------------------------------------
// void CLcServiceImpl::LaunchLocationCentreL
// ---------------------------------------------------------------------------
//
void CLcServiceImpl::LaunchLocationCentreL( 
              const TLcLocationAppFilter&             aLocationAppFilter,
                    CLcLocationAppInfo::TLcLaunchMode aLaunchMode,                        
                    MLcAppExitObserver*               aChainedAppExitObserver )
    {
    DEBUG("+ CLcServiceImpl::LaunchLocationCentreL")
    // First select a Location based Application from the list
    TPtrC identifier = SelectLocationApplicationL( aLocationAppFilter );
    if ( !identifier.Length())
        {
        return;
        }    
    
    // Launch the corresponding application.
    LaunchLocationApplicationL( identifier, aLaunchMode, aChainedAppExitObserver );
    DEBUG("- CLcServiceImpl::LaunchLocationCentreL")
    }
    
// ---------------------------------------------------------------------------
// void CLcServiceImpl::LaunchLocationCentreL
// ---------------------------------------------------------------------------
//
void CLcServiceImpl::LaunchLocationCentreL(
      const RPointerArray<CLcService::CLcLaunchParam>& aIncludeAppArray,
      MLcAppExitObserver*                              aChainedAppExitObserver )
    {
    // Form an array of applications identifiers which can be passed to the
    // selection function
    RArray<TPtrC>  appArray;
    CleanupClosePushL( appArray );
    
    TInt count = aIncludeAppArray.Count();    
    for( TInt i = 0; i < count; i++ )
        {
        User::LeaveIfError( appArray.Append( aIncludeAppArray[i]->Id()));
        }
        
    // First select a Location based Application from the list
    TPtrC identifier = SelectLocationApplicationL( appArray, ETrue );    
    if ( !identifier.Length())
        {
        return;
        }
        
    CLcLocationAppInfo::TLcLaunchMode launchmode = CLcLocationAppInfo::EDefaultMode;
    // Obtain the launch mode for that application            
    for ( TInt i = 0; i < count; i++ )
        {
        if ( !appArray[i].Compare( identifier ))
            {
            launchmode = aIncludeAppArray[i]->LaunchMode();
            break;
            }
        }
        
    // Launch the corresponding application.
    LaunchLocationApplicationL( identifier, launchmode, aChainedAppExitObserver ); 
    
    // Pop and Destroy the application array        
    CleanupStack::PopAndDestroy();
    }
    
// ---------------------------------------------------------------------------
// void CLcServiceImpl::LaunchLocationCentreL
// ---------------------------------------------------------------------------
//
void CLcServiceImpl::LaunchLocationCentreL( 
                    const RArray<TPtrC>&              aExcludeAppArray,
                    CLcLocationAppInfo::TLcLaunchMode aLaunchMode,
                    MLcAppExitObserver*               aChainedAppExitObserver )
    {
    // First select a Location based Application from the list
    TPtrC identifier = SelectLocationApplicationL( aExcludeAppArray, EFalse );
    if ( !identifier.Length())
        {
        return;
        }    
    
    // Launch the corresponding application.
    LaunchLocationApplicationL( identifier, aLaunchMode, aChainedAppExitObserver );    
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::SelectLocationApplicationL
// ---------------------------------------------------------------------------
//
TPtrC CLcServiceImpl::SelectLocationApplicationL(
                        const TLcLocationAppFilter&     aLocationAppFilter )
    {
    // If the pop-up dialog is currently being displayed then cannot proceed with
    // the request.
    if ( iPopUp )
        {
        User::Leave( KErrInUse );
        }
    
    iPopupOutStanding = ELcPopupWithFiltering;
    
    // Delete any existing filter. This condition should never occur. Just a safe
    // check.
    delete iFilter;
    iFilter = NULL;
    
    // Copy the filter contents
    iFilter = new ( ELeave ) TLcLocationAppFilter( aLocationAppFilter );
      
    // Obtain the list of applications from the Location Centre Server and
    // launch the Location Centre pop-up with that list.    
    CLcLocationAppInfoArray* array = GetLocationApplicationsL( aLocationAppFilter );
                                  
    // The ownership of the array is transferred.
    TPtrC  appId(KNullDesC());
    TRAPD( error, appId.Set( SelectLocationApplicationL( array )));
    
    // Delete the filter before any operation on the result        
    delete iFilter;
    iFilter = NULL;
     
    // Handle Error 
    if ( error )
        {
        if ( iPopUp )
            {
            iPopUp->CancelPopup();            
            }
        iPopUp = NULL;
        
        delete iPopUpListBox;
        iPopUpListBox = NULL;
        
        User::Leave( error );        
        }        
    return appId;        
    }
    
// ---------------------------------------------------------------------------
// void CLcServiceImpl::SelectLocationApplicationL
// ---------------------------------------------------------------------------
//
TPtrC CLcServiceImpl::SelectLocationApplicationL(
                            const RArray<TPtrC>&      aAppArray,
                                  TBool               aIncludeFlag )
    {
    // If the pop-up dialog is currently being displayed then cannot proceed with
    // the request.
    if ( iPopUp )
        {
        User::Leave( KErrInUse );
        }
     
    // Reset and Destroy the existing array.
    iAppArray.Reset();
    
    if ( aIncludeFlag )
        {
        iPopupOutStanding = ELcPopupWithSpecifiedApps;
        }
    else
        {
        iPopupOutStanding = ELcPopupWithoutSpecifedApps;
        }
        
    // Create the array with the new elements
    TInt count = aAppArray.Count();
    for ( TInt i = 0; i < count; i++ )
        {
        User::LeaveIfError( iAppArray.Append( aAppArray[i] ));
        }
        
    // Obtain the list of applications from the Location Centre Server and
    // launch the Location Centre pop-up with that list.    
    CLcLocationAppInfoArray* array = 
                    LcSyncOperation::GetLocationApplicationsL( iSession,
                                                               aAppArray,
                                                               aIncludeFlag );
                                  
    // The ownership of the array is transferred.
    TPtrC  appId(KNullDesC());
    TRAPD( error, appId.Set( SelectLocationApplicationL( array )));
    
    // Reset and destroy the array
    iAppArray.Reset();
      
    // Handle Error    
    if ( error )
        {
        if ( iPopUp )
            {
            iPopUp->CancelPopup();            
            }
        iPopUp = NULL;
        
        delete iPopUpListBox;
        iPopUpListBox = NULL;
        
        User::Leave( error );
        }
    return appId;         
    }
    
// ---------------------------------------------------------------------------
// CLcLocationAppInfoArray* CLcServiceImpl::GetLocationApplicationsL
// ---------------------------------------------------------------------------
//    
CLcLocationAppInfoArray* CLcServiceImpl::GetLocationApplicationsL(
            const TLcLocationAppFilter&         aLocationAppFilter )
    {
    return LcSyncOperation::GetLocationApplicationsL( iSession,
    												  aLocationAppFilter );
    }
    
// ---------------------------------------------------------------------------
// void CLcServiceImpl::GetLocationApplicationsL
// ---------------------------------------------------------------------------
//    
void CLcServiceImpl::GetLocationApplications(
                            TRequestStatus&             aStatus,
                      const TLcLocationAppFilter&       aLocationAppFilter,                            
                            CLcLocationAppInfoArray*&   aAppInfoArray)
    {
    TRAPD( error, GetLocationApplicationsL( aStatus,
    										aLocationAppFilter,
    										aAppInfoArray ));
	if ( error )
		{
		TRequestStatus* status = &aStatus;
		User::RequestComplete( status , error );
		}
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::CancelGetLocationApplications
// ---------------------------------------------------------------------------
//     
void CLcServiceImpl::CancelGetLocationApplications()
    {
    // If there is an outstanding request then complete the same with KErrCancel.
    if ( iAsyncOperation )
    	{
    	iAsyncOperation->CancelGetLocationApplications();
    	User::RequestComplete( iStatus, KErrCancel );
    	
    	// We can now delete the asynchronous operation
    	delete iAsyncOperation;
    	iAsyncOperation = NULL;
    	} 
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::LaunchLocationApplicationL
// ---------------------------------------------------------------------------
// 
void CLcServiceImpl::LaunchLocationApplicationL( 
                const TDesC&                      aAppIdentifier,
                CLcLocationAppInfo::TLcLaunchMode aLaunchMode,
                MLcAppExitObserver*               aChainedAppExitObserver )
    {
    DEBUG("+ CLcServiceImpl::LaunchLocationApplicationL" )
    
    // Obtain the Location Application Information from Location Centre Server.
    CLcBasicAppInfo* appInfo = 
    	LcSyncOperation::GetLocationAppInfoL( iSession, aAppIdentifier );
    CleanupStack::PushL( appInfo );
   
    // Resolve the model in which the Application must be launched.
    if ( aLaunchMode == CLcLocationAppInfo::EDefaultMode )
    	{
    	// Since this is a Local copy we can use the same for handling
    	// Launch mode changes.
    	aLaunchMode = 
    		static_cast<CLcLocationAppInfo::TLcLaunchMode>( appInfo->LaunchMode());
    	}
    	    	
	// Now Launch the Location based Application or Content/Service    	
    iAppLauncher->LaunchLocationApplicationL( 
			appInfo->ApplicationType(),
            appInfo->ApplicationData(),
            ( aLaunchMode == CLcLocationAppInfo::EStandAloneMode ) ? ETrue : EFalse,
            appInfo->CommandLineParamters(),
            aChainedAppExitObserver );

	CleanupStack::PopAndDestroy( appInfo );                                          
	
	DEBUG("- CLcServiceImpl::LaunchLocationApplicationL" )                                          
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::SetObserverL
// ---------------------------------------------------------------------------
// 
void CLcServiceImpl::SetObserverL( MLcNotification&     aObserver )
    {
    if ( iObserver )
        {
        User::Leave( KErrAlreadyExists );
        }
    
    iObserver = &aObserver;
    
    iNotificationAO->IssueRequest();
    }

// ---------------------------------------------------------------------------
// TInt CLcServiceImpl::RemoveObserver
// ---------------------------------------------------------------------------
//                                         
TInt CLcServiceImpl::RemoveObserver()
    {
    if ( !iObserver )
        {
        return KErrNotFound;
        }
    
    iObserver = NULL;
    
    // If there is a popup outstanding then do nothing. If not remove the
    // notification
    if ( !iPopUp )
        {
        iNotificationAO->CancelRequest();        
        }
        
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::LcStatusChangedL
// ---------------------------------------------------------------------------
// 
void CLcServiceImpl::LcStatusChangedL( TInt aErrorCode )
    {
    // If we are displaying the pop-up then we need to transfer the changes
    // to the pop-up first
    if ( iPopUp )
        {
        // Obtain the new list of applications from the Location Centre Server and
        // update the Location Centre pop-up with that list.    
        CLcLocationAppInfoArray* array = NULL;
        TInt error = KErrNone;
                        
        switch( iPopupOutStanding )
            {
            case ELcPopupWithFiltering:
                {                
                // Incase we face any errors in retrival then we can Ignore the
                // updations
                TRAP( error, array = GetLocationApplicationsL( *iFilter ));
                break;
                }
            case ELcPopupWithSpecifiedApps:
            case ELcPopupWithoutSpecifedApps:            
                {
                TBool includeflag = EFalse;
                if ( iPopupOutStanding == ELcPopupWithSpecifiedApps )
                    {
                    includeflag = ETrue;
                    }
                    
                // Incase we face any errors in retrival then we can Ignore the
                // updations
                TRAP( error, array = LcSyncOperation::GetLocationApplicationsL( 
                                                        iSession, iAppArray, includeflag ));
                break;
                }
            default:
                {
                break;
                }
            }
           
        if ( !error && array )
            {
            // The ownership of the array is transferred to the list box.
            TRAP_IGNORE( CleanupStack::PushL( array ); 
                         iPopUpListBox->UpdateListBoxL( array );
                         CleanupStack::Pop( array );
                       );
            }
        else if ( KErrNotFound == error )
            {
            if ( iPopUp )
                {
                iPopUp->CancelPopup();            
                }
            iPopUp = NULL;
            
            delete iPopUpListBox;
            iPopUpListBox = NULL;            
            }
        }
        
    // Notify the client regarding the changes to Location Centre Registry
    if ( iObserver )
        {
        iObserver->LcStatusChangedL( aErrorCode );
        }   
    }

// ---------------------------------------------------------------------------
// void CLcServiceImpl::OperationComplete
// ---------------------------------------------------------------------------
// 
void CLcServiceImpl::OperationComplete( TInt aError )
	{
	User::RequestComplete( iStatus, aError );
	
	// We can now delete the asynchronous operation
	delete iAsyncOperation;
	iAsyncOperation = NULL;	
	}

// ---------------------------------------------------------------------------
// void CLcServiceImpl::GetLocationApplicationsL
// ---------------------------------------------------------------------------
// 	
void CLcServiceImpl::GetLocationApplicationsL( 
                TRequestStatus&             aStatus,
          const TLcLocationAppFilter&       aLocationAppFilter,
                CLcLocationAppInfoArray*&   aAppInfoArray )
	{
    aStatus = KRequestPending;
    
    // If there is an asynchronous operation then leave with KErrInUse
    if ( iAsyncOperation )
    	{
    	User::Leave( KErrInUse );
    	}
    	
	// Create the Asynchronous Operations class
	iAsyncOperation = CLcAsyncOperation::NewL( iSession, *this );
	    	
    // Set the status to KRequestPending
    aStatus = KRequestPending;
    iStatus = &aStatus;
    
    // Issue the request to the ASP
    iAsyncOperation->GetLocationApplicationsL( aLocationAppFilter,
    										   aAppInfoArray );	
	}

// ---------------------------------------------------------------------------
// void CLcServiceImpl::SelectLocationApplicationL
// ---------------------------------------------------------------------------
//
TPtrC CLcServiceImpl::SelectLocationApplicationL( 
                                CLcLocationAppInfoArray*   aAppInfoArray )
    {
    // The App Info arrays ownership is tranferred to the List. So push it
    // to the Cleanup stack until the ownership is completely transferred.
    CleanupStack::PushL( aAppInfoArray );
    
    iPopUpListBox = new ( ELeave ) CLcPopupListBox( aAppInfoArray );
    CleanupStack::Pop( aAppInfoArray );
    
    // Construct the popup with the list
    iPopUp = CAknPopupList::NewL( iPopUpListBox, 
                                  R_AVKON_SOFTKEYS_SELECT_CANCEL__SELECT,
                                  AknPopupLayouts::EMenuGraphicWindow );  
    iPopUpListBox->ConstructL( iPopUp );    
    // iPopUp->SetBorder( AknBorderId::EAknBorderMenuPopup );								                          
    
    // Set up notification events
    iNotificationAO->IssueRequest();
                             
    // Display the pop-up and let user selection.                             
    TInt popupOk = iPopUp->ExecuteLD();
    iPopUp = NULL;
    
    // Only we are observing for notifications. We dont need it anymore
    // Cancel it
    if ( !iObserver )
        {
        iNotificationAO->CancelRequest();
        }
        
    if ( popupOk )
        {
        delete iSelectedAppId;        
        iSelectedAppId = NULL;
                
        iSelectedAppId = iPopUpListBox->AppInfoId().AllocL();
        
        delete iPopUpListBox;
        iPopUpListBox = NULL;
        
        return *iSelectedAppId;
        }
    else
        {
        delete iPopUpListBox;
        iPopUpListBox = NULL;
        
        return TPtrC();
        }
    }
    
// End of File