diff -r 000000000000 -r 522cd55cc3d7 locationcentre/lcservice/src/lcsyncoperation.cpp --- /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 + +// 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& 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( 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