--- /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