locationcentre/lcservice/src/lcsyncoperation.cpp
changeset 0 522cd55cc3d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationcentre/lcservice/src/lcsyncoperation.cpp	Tue Feb 02 00:16:03 2010 +0200
@@ -0,0 +1,544 @@
+/*
+* 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:  Handles all the Synchronous operations with the Location
+*                Centre Client Session
+*
+*/
+
+
+// SYSTEM INCLUDES
+#include <s32mem.h>
+
+// USER INCLUDES
+#include "lcsyncoperation.h"
+#include "lcclientsession.h"
+#include "lcipcparams.h"
+#include "lcdebug.h"
+
+// CONSTANT DEFINTIONS
+const TInt  KLcLengthofInteger  = 4;
+
+// ----- Member funtions for LcSyncOperation ---------------------------------
+
+// ---------------------------------------------------------------------------
+// CLcLocationAppInfoArray* CLcServiceImpl::GetLocationApplicationsL
+// ---------------------------------------------------------------------------
+//    
+CLcLocationAppInfoArray* LcSyncOperation::GetLocationApplicationsL(
+											  RLcClientSession&   	aSession,
+							            const TLcLocationAppFilter& aLocationAppFilter )
+    {
+    DEBUG("+ LcSyncOperation::GetLocationApplicationsL")
+    DEBUG("Filtering")
+    
+    // This function needs to obtain a list of all applications. This would
+    // first require to obtain the length of the buffer that needs to be
+    // passed from the client to the server to pack the array.
+    CBufFlat* lengthBuf = CBufFlat::NewL( KLcLengthofInteger );
+    CleanupStack::PushL( lengthBuf );
+    
+    // Set the size of this buffer to 4. This is required because we dont
+    // actually fill this buffer but expect the server to fill it. In that case
+    // if we dont set the expected length, the server would fail with
+    // KrrBadDescriptor.
+    lengthBuf->ResizeL( KLcLengthofInteger );
+    
+    // Fill the IPC argument structure with the Length buffer, the server
+    // will write the data onto this buffer.
+    TIpcArgs    args;
+    
+    // Pass the filter parameters to the Location Centre Server
+    TPckg< TLcLocationAppFilter >    filterBuffer( aLocationAppFilter );
+    
+    // By the IPC exchange parameter defintion, this must be the first
+    // argument to the IPC message.
+    args.Set( 0, &filterBuffer );
+    
+    // Set the buffer pointer to the start of the Length buffer
+    TPtr8 bufPtr( const_cast< TUint8 *>( lengthBuf->Ptr( 0 ).Ptr()),
+                  0,
+                  KLcLengthofInteger );
+    
+    // This will be the second argument passed to this IPC message.
+    args.Set( 1, &bufPtr);
+    
+    // Send a synchrnous message to the server to obtain the length. On return the
+    // server is expected to pack the length of the Application information
+    // arrays in the LengthBuffer pointer.
+    User::LeaveIfError( aSession.SendReceive( ELcFilteredAppsBufferLength, args ));
+
+    // If the server has not set the buffer then leave with KErrNotFound
+    if ( !bufPtr.Length())
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    // Obtain the length from the Length buffer;
+    RBufReadStream  readStream( *lengthBuf, 0 );
+    CleanupClosePushL( readStream );
+    TUint length = readStream.ReadInt32L();
+    CleanupStack::PopAndDestroy( 2, lengthBuf );   // readStream
+    
+    // If the server has returned a length of 0, then there are no applications
+    // registered with Location Centre.
+    if ( !length )
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    // Now that the length has been obtained. Allocate the descriptor
+    // of suitable length and send it across to the server.
+    CBufFlat* appInfoBuf = CBufFlat::NewL( length );
+    CleanupStack::PushL( appInfoBuf );
+    
+    // Set the actual size to 'length' obtained in the previous IPC. This is required
+    // because we dont actually fill this buffer but expect the server to fill it.
+    // In that case if we dont set the expected length, the server would fail with
+    // KrrBadDescriptor.
+    appInfoBuf->ResizeL( length );
+    
+    // Fill the IPC argument structure with the Application info buffer, the server
+    // will write the data onto this buffer.
+    
+    // Pass the filter parameters to the Location Centre Server
+    // By the IPC exchange parameter defintion, this must be the first
+    // argument to the IPC message.
+    args.Set( 0, &filterBuffer );
+    
+    // Set the buffer pointer to the start of the Length buffer
+    bufPtr.Set( const_cast< TUint8 *>( appInfoBuf->Ptr( 0 ).Ptr()),
+                0,
+                length );
+    
+    // This will be the second argument passed to this IPC message.
+    args.Set( 1, &bufPtr);
+    
+    // Send a synchrnous message to the server to obtain the length. On return the
+    // server is expected to pack the length of the Application information
+    // arrays in the LengthBuffer pointer.
+    TInt error =  aSession.SendReceive( ELcFilteredApps, args );
+    
+	// If the Retrieval function completes with KErrOverflow then there has been
+	// an update to the registry since the time we obtained the length.
+	if ( KErrOverflow == error )
+		{
+		// Cleanup the current state and Re-issue the same request again
+		CleanupStack::PopAndDestroy( appInfoBuf );
+		return GetLocationApplicationsL( aSession, aLocationAppFilter );
+		}
+	else if( error )
+		{
+		User::Leave( error );
+		}
+
+    // If the server has not set the buffer then leave with KErrNotFound
+    if ( !bufPtr.Length())
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Parse the Application information array to obtain the array
+    RBufReadStream  appReadStream( *appInfoBuf, 0 );
+    CleanupClosePushL( appReadStream );
+    
+    CLcLocationAppInfoArray* array = ParseLocAppBufferL( appReadStream );
+    
+    CleanupStack::PopAndDestroy( 2, appInfoBuf );   // appReadStream
+
+    DEBUG("- LcSyncOperation::GetLocationApplicationsL")
+    
+    return array;
+
+    }
+
+// ---------------------------------------------------------------------------
+// CLcLocationAppInfoArray* LcSyncOperation::GetLocationApplicationsL
+// ---------------------------------------------------------------------------
+//     
+CLcLocationAppInfoArray* LcSyncOperation::GetLocationApplicationsL(
+                                      RLcClientSession&   		aSession,
+                                      const RArray<TPtrC>&      aAppArray,
+                                            TBool               aIncludeFlag )
+    {
+        
+    // Obtain the array of Application Identifiers in a buffer
+    RLcIpcAppIdArray        idArray;
+    CleanupStack::PushL( TCleanupItem( RLcIpcAppIdArray::ResetAndDestroyIdArray, &idArray ));
+    
+    // Append all the identifiers to the Array    
+    for ( TInt i = 0; i < aAppArray.Count(); i++ )
+        {
+        // Create a new element
+        HBufC* newElement = HBufC::NewLC( aAppArray[i].Length());
+        
+        // Copy the contents to the buffer and append it to the array
+        newElement->Des().Copy( aAppArray[i] );
+        User::LeaveIfError( idArray.Append( newElement ));
+        
+        // Now that the ownership is transferred, the content can be removed from
+        // the Cleanup stack
+        CleanupStack::Pop();
+        }
+    
+    // Create the buffer for packing the Application Information
+    // structure and pack the contents into this buffer
+    CBufFlat* buffer = CBufFlat::NewL( idArray.BufferLength());
+    CleanupStack::PushL( buffer );
+    
+    RBufWriteStream writeStream( *buffer, 0 );
+    CleanupClosePushL( writeStream );                
+    idArray.ExternalizeL( writeStream );
+    CleanupStack::PopAndDestroy(); // writeStream
+                   
+    // This needs to be popped inorder to Close the idArray;
+    CleanupStack::Pop( 2 ); // buffer, idArray
+    idArray.ResetAndDestroy();
+    idArray.Close();
+    
+    // Now reinsert the App buffer back into the Cleanupstack
+    CleanupStack::PushL( buffer );
+       
+    // This function needs to obtain a list of all applications. This would
+    // first require to obtain the length of the buffer that needs to be
+    // passed from the client to the server to pack the array.
+    
+    TIpcArgs    args;
+        
+    // First pack the application id array to the IPC args
+    // By the IPC exchange parameter defintion, this must be the first
+    // argument to the IPC message.
+    TPtr8 appArrayPtr( buffer->Ptr(0));
+      
+    args.Set( 0, &appArrayPtr );
+     
+    // The second argument is the Include flag
+    args.Set( 1, aIncludeFlag );
+               
+    CBufFlat* lengthBuf = CBufFlat::NewL( KLcLengthofInteger );
+    CleanupStack::PushL( lengthBuf );
+    
+    // Set the size of this buffer to 4. This is required because we dont
+    // actually fill this buffer but expect the server to fill it. In that case
+    // if we dont set the expected length, the server would fail with
+    // KrrBadDescriptor.
+    lengthBuf->ResizeL( KLcLengthofInteger );
+ 
+    // Set the buffer pointer to the start of the Length buffer
+    TPtr8 bufPtr( const_cast< TUint8 *>( lengthBuf->Ptr( 0 ).Ptr()),
+                  0,
+                  KLcLengthofInteger );
+    
+    // This will be the third argument passed to this IPC message.
+    args.Set( 2, &bufPtr);
+    
+    // Send a synchrnous message to the server to obtain the length. On return the
+    // server is expected to pack the length of the Application information
+    // arrays in the LengthBuffer pointer.
+    User::LeaveIfError( aSession.SendReceive( ELcSpecifiedAppsBufferLength, args ));
+
+    // If the server has not set the buffer then leave with KErrNotFound
+    if ( !bufPtr.Length())
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    // Obtain the length from the Length buffer;
+    RBufReadStream  readStream( *lengthBuf, 0 );
+    CleanupClosePushL( readStream );
+    TUint length = readStream.ReadInt32L();
+    CleanupStack::PopAndDestroy( 2, lengthBuf );   // readStream
+    
+    // If the server has returned a length of 0, then there are no applications
+    // registered with Location Centre.
+    if ( !length )
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    // Now that the length has been obtained. Allocate the descriptor
+    // of suitable length and send it across to the server.
+    CBufFlat* appInfoBuf = CBufFlat::NewL( length );
+    CleanupStack::PushL( appInfoBuf );
+    
+    // Set the actual size to 'length' obtained in the previous IPC. This is required
+    // because we dont actually fill this buffer but expect the server to fill it.
+    // In that case if we dont set the expected length, the server would fail with
+    // KrrBadDescriptor.
+    appInfoBuf->ResizeL( length );
+    
+    // Fill the IPC argument structure with the Application info buffer, the server
+    // will write the data onto this buffer.
+    
+    // Pass the Application ids to the Location Centre Server
+    // By the IPC exchange parameter defintion, this must be the first
+    // argument to the IPC message.
+    args.Set( 0, &appArrayPtr );
+    
+    // The second argument is the Include flag
+    args.Set( 1, aIncludeFlag );
+    
+    // Set the buffer pointer to the start of the Length buffer
+    bufPtr.Set( const_cast< TUint8 *>( appInfoBuf->Ptr( 0 ).Ptr()),
+                0,
+                length );
+    
+    // This will be the third argument passed to this IPC message.
+    args.Set( 2, &bufPtr);
+    
+    // Send a synchrnous message to the server to obtain the length. On return the
+    // server is expected to pack the length of the Application information
+    // arrays in the LengthBuffer pointer.
+    TInt error = aSession.SendReceive( ELcSpecifiedApps, args );
+
+	// If the Retrieval function completes with KErrOverflow then there has been
+	// an update to the registry since the time we obtained the length.
+	if ( KErrOverflow == error )
+		{
+		// Cleanup the current state and Re-issue the same request again
+		CleanupStack::PopAndDestroy( 2, buffer );
+		return GetLocationApplicationsL( aSession, aAppArray, aIncludeFlag );
+		}
+	else if( error )
+		{
+		User::Leave( error );
+		}
+		
+		
+    // If the server has not set the buffer then leave with KErrNotFound
+    if ( !bufPtr.Length())
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Parse the Application information array to obtain the array
+    RBufReadStream  appReadStream( *appInfoBuf, 0 );
+    CleanupClosePushL( appReadStream );
+    
+    CLcLocationAppInfoArray* array = LcSyncOperation::ParseLocAppBufferL( appReadStream );
+    
+    CleanupStack::PopAndDestroy( 3, buffer );   // idArray, appInfoBuf and buffer
+
+    return array;  
+    }
+    
+// ---------------------------------------------------------------------------
+// CLcBasicAppInfo* LcSyncOperation::GetLocationAppInfoL
+// ---------------------------------------------------------------------------
+// 
+CLcBasicAppInfo* LcSyncOperation::GetLocationAppInfoL( 
+									RLcClientSession&   aSession,
+							  const TDesC&				aIdentifier )
+	{
+    // This function needs to obtain the Length of the buffer which needs to be
+    // passed to the Server to pack the Location Application Information.
+    CBufFlat* lengthBuf = CBufFlat::NewL( KLcLengthofInteger );
+    CleanupStack::PushL( lengthBuf );
+    
+    // Set the size of this buffer to 4. This is required because we dont
+    // actually fill this buffer but expect the server to fill it. In that case
+    // if we dont set the expected length, the server would fail with
+    // KrrBadDescriptor.
+    lengthBuf->ResizeL( KLcLengthofInteger );
+    
+    // Fill the IPC argument structure with the Length buffer, the server
+    // will write the data onto this buffer.
+    TIpcArgs    args;
+    
+    // By the IPC exchange parameter defintion, the first argument must the
+    // Identifier name
+    args.Set( 0, &aIdentifier );
+    
+    // Set the buffer pointer to the start of the Length buffer
+    TPtr8 bufPtr( const_cast< TUint8 *>( lengthBuf->Ptr( 0 ).Ptr()),
+                  0,
+                  KLcLengthofInteger );
+    
+    // This will be the second argument passed to this IPC message.
+    args.Set( 1, &bufPtr);
+    
+    // Send a synchrnous message to the server to obtain the length. On return the
+    // server is expected to pack the length of the Application information
+    // arrays in the LengthBuffer pointer.
+    User::LeaveIfError( aSession.SendReceive( ELcAppInfoLength, args ));
+
+    // If the server has not set the buffer then leave with KErrNotFound
+    if ( !bufPtr.Length())
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    // Obtain the length from the Length buffer;
+    RBufReadStream  readStream( *lengthBuf, 0 );
+    CleanupClosePushL( readStream );
+    TUint length = readStream.ReadInt32L();
+    CleanupStack::PopAndDestroy( 2, lengthBuf );   // readStream
+    
+    // If the server has returned a length of 0, then there are no applications
+    // registered with Location Centre.
+    if ( !length )
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    // Now that the length has been obtained. Allocate the descriptor
+    // of suitable length and send it across to the server.
+    CBufFlat* appInfoBuf = CBufFlat::NewL( length );
+    CleanupStack::PushL( appInfoBuf );
+    
+    // Set the actual size to 'length' obtained in the previous IPC. This is required
+    // because we dont actually fill this buffer but expect the server to fill it.
+    // In that case if we dont set the expected length, the server would fail with
+    // KrrBadDescriptor.
+    appInfoBuf->ResizeL( length );
+    
+    // Fill the IPC argument structure with the Application info buffer, the server
+    // will write the data onto this buffer.
+    
+    // Pass the Application Identifier to the Location Centre Server
+    // By the IPC exchange parameter defintion, this must be the first
+    // argument to the IPC message.
+    args.Set( 0, &aIdentifier );
+    
+    // Set the buffer pointer to the start of the Length buffer
+    bufPtr.Set( const_cast< TUint8 *>( appInfoBuf->Ptr( 0 ).Ptr()),
+                0,
+                length );
+    
+    // This will be the second argument passed to this IPC message.
+    args.Set( 1, &bufPtr);
+    
+    // Send a synchrnous message to the server to obtain the length. On return the
+    // server is expected to pack the length of the Application information
+    // in the buffer pointer.
+    TInt error = aSession.SendReceive( ELcAppInfo, args );
+
+	// If the Retrieval function completes with KErrOverflow then there has been
+	// an update to the registry since the time we obtained the length.
+	if ( KErrOverflow == error )
+		{
+		// Cleanup the current state and Re-issue the same request again
+		CleanupStack::PopAndDestroy( appInfoBuf );
+		return GetLocationAppInfoL( aSession, aIdentifier );
+		}
+	else if( error )
+		{
+		User::Leave( error );
+		}
+		
+    // If the server has not set the buffer then leave with KErrNotFound
+    if ( !bufPtr.Length())
+        {
+        User::Leave( KErrNotFound );
+        }
+        
+    // Parse the Application information structure to obtain the Application
+    // information structure
+    RBufReadStream  appReadStream( *appInfoBuf, 0 );
+    CleanupClosePushL( appReadStream );
+    
+    CLcBasicAppInfo* appInfo = CLcBasicAppInfo::NewLC();
+    appInfo->InternalizeL( appReadStream );
+    CleanupStack::Pop( appInfo );
+    
+    CleanupStack::PopAndDestroy( 2, appInfoBuf );   // appReadStream
+
+    return appInfo;	
+	}
+	
+// ---------------------------------------------------------------------------
+// CLcLocationAppInfoArray* LcSyncOperation::ParseLocAppBufferL
+// ---------------------------------------------------------------------------
+// 
+CLcLocationAppInfoArray* LcSyncOperation::ParseLocAppBufferL( 
+                                                RReadStream&   aReadStream )
+    {
+    DEBUG("+ LcSyncOperation::ParseLocAppBufferL")
+        
+    CLcLocationAppInfoArray* appArray = CLcLocationAppInfoArray::NewLC();
+    
+    // Parse the contents into RLcIpcAppInfoArray type.
+    RLcIpcAppInfoArray  ipcArray;
+    CleanupStack::PushL( TCleanupItem( RLcIpcAppInfoArray::ResetAndDestroyAppArray, &ipcArray ));
+    
+    // Internalize the array onto the ipcArray structure.
+    ipcArray.InternalizeL( aReadStream );
+
+    // Pack the Application info array
+    for ( TInt i = 0; i < ipcArray.Count(); i++ )
+        {
+        
+        // Form the Application information object corresponding to
+        // this ipcAppInfo.
+        
+        // Create a new Application Information object. This object will
+        // be populated and the appended to the appArray.
+        CLcLocationAppInfo* appInfo = CLcLocationAppInfo::NewLC();
+        
+        // Set the Unique identifer for the application
+        appInfo->SetIdL( ipcArray[i]->Id());
+        
+        // Set the display name of the application
+        appInfo->SetNameL( ipcArray[i]->Name());
+        
+        // Set the Launch Mode for the application
+        // There is no need to check the launch mode and compare it with
+        // the values of TLcLaunchMode. Internally its ensured that the 
+        // server would only set the parameter based in TLcLaunchMode.
+        appInfo->SetLaunchMode( static_cast<CLcLocationAppInfo::
+                            TLcLaunchMode>( ipcArray[i]->LaunchMode()));
+        
+        // Set the Application characteristics
+        appInfo->SetApplicationCharacteristics( 
+                            ipcArray[i]->ApplicationCharacteristics());
+        
+        // Set the system characteristics
+        appInfo->SetSystemCharacteristics( ipcArray[i]->SystemCharacteristics());
+         
+        // Load the application Icon Related Data
+        if ( ipcArray[i]->IconFile().Compare( KNullDesC ))
+        	{
+        	// The Icon file name is specified. So Load the icons from the 
+        	// Icon file. So we can set these values for the Icon file.
+        	appInfo->SetIconL( ipcArray[i]->IconFileType(),
+        					   ipcArray[i]->IconFile(),
+        					   ipcArray[i]->FrameNo());
+        	}
+        else if ( ipcArray[i]->ApplicationType() == ELcNativeApplication )
+        	{
+        	// Only native applications are handled here.
+        	// Here we have to pass the Application UID as the Icon data since
+        	// the Icon will be loaded from the App shell
+        	appInfo->SetIconL( ipcArray[i]->IconFileType(),
+        					   ipcArray[i]->ApplicationData());        	
+        	}
+        		   
+        appArray->AppendL( appInfo );
+        CleanupStack::Pop( appInfo );
+        }
+    CleanupStack::PopAndDestroy(); // ipcArray
+    
+    // If there are no elements in the array then that means that there
+    // are no applications registered with LC. So leave with KErrNotFound
+    if ( !appArray->Count())
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    CleanupStack::Pop( appArray ); 
+    
+    DEBUG("- LcSyncOperation::ParseLocAppBufferL")
+           
+    return appArray;
+    }	                                                                                                            
+// End of File