/*
* Copyright (c) 2002-2008 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: Skin server client.
*
*/
// INCLUDE FILES
#include <AknsSrvClient.h>
#include "AknsSrv.h"
#include "AknsSkinChangeHandler.h"
#include "AknsSrvClientMemberData.h"
#include <AknsImageAttributeData.h>
#include "AknsSrvUtils.h"
#include <AknUtils.h>
#include <akniconconfig.h>
#include "AknsDebug.h"
#include <hal.h>
#include <badesca.h>
// CONSTANTS
// Number of re-tries for skin server connection.
const TInt KAknSkinSrvConnectionTries = 2;
// Number of message slots.
const TUint KAknSkinSrvDefaultMessageSlots = 2;
// ============================= LOCAL FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// AknsSrvCArrayPtrCleanup
// Cleanup operation for CArrayPtr<CAknsSrvSkinInformationPkg>
// -----------------------------------------------------------------------------
static void AknsSrvCArrayPtrCAknsSrvSkinInformationPkgCleanup( TAny* aItem )
{
CArrayPtr<CAknsSrvSkinInformationPkg>* array = static_cast<
CArrayPtr<CAknsSrvSkinInformationPkg>*>( aItem );
array->ResetAndDestroy();
delete array;
}
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// RAknsSrvSession::RAknsSrvSession
// C++ constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
EXPORT_C RAknsSrvSession::RAknsSrvSession()
: RSessionBase(), iMemberData(NULL)
{
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Connect
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::Connect(
MAknsSkinChangeObserver* aObserver,
TInt aPriority )
{
AKNS_TRACE_INFO("RAknsSrvSession::Connect ENTERED");
if( iHandle )
{
AKNS_TRACE_INFO("RAknsSrvSession::Connect Handle exists, RETURN KErrNone");
return KErrNone;
}
// Connect to server and make sure this can't cause 2 servers launch
// if 2 clients are trying to connect simultaneously.
AKNS_TRACE_INFO("RAknsSrvSession::Connect Creating member data");
iMemberData = new TAknsSrvClientMemberData;
if (!iMemberData)
{
AKNS_TRACE_ERROR("RAknsSrvSession::Connect NO MEMORY");
return KErrNoMemory;
}
iMemberData->iHandler = NULL;
iMemberData->iObserver = aObserver;
TInt err( KErrNone );
for ( TInt tries = 0; tries < KAknSkinSrvConnectionTries ; tries++ )
{
AKNS_TRACE_INFO("RAknsSrvSession::Connect Creating session");
err = CreateSession( KAknSkinSrvName, Version(),
KAknSkinSrvDefaultMessageSlots );
AKNS_TRACE_INFO1("RAknsSrvSession::Connect Session create ret %d", err);
// Break if connected to existing server or if the problem is
// other than missing server.
if ( err == KErrNone ||
( err != KErrNotFound && err != KErrServerTerminated ) )
{
break;
}
AKNS_TRACE_INFO("RAknsSrvSession::Connect Trying to start the server");
err = StartServer(); // try start a new server
AKNS_TRACE_INFO1("RAknsSrvSession::Connect StartServer ret %d", err);
// If server launched ok or someone else got to launch it first,
// try connect again.
if( (err!=KErrNone) && (err!=KErrAlreadyExists) )
{
break; // server not launched: don't cycle round again
}
}
if (err != KErrNone)
{
AKNS_TRACE_ERROR1("RAknsSrvSession::Connect CREATE SESSION FAILED, err=%d", err);
delete iMemberData;
iMemberData = NULL;
return err;
}
// Check if the user wanted us to notify skin changes and create
// the Active object to handle the notification events. Otherwise
// just return.
if( iMemberData->iObserver)
{
AKNS_TRACE_INFO("RAknsSrvSession::Connect Observer required");
__ASSERT_DEBUG( CActiveScheduler::Current(), User::Panic(
KAknSkinSrvPanicCategory, EAknsSrvNoActiveScheduler ) );
iMemberData->iHandler = new CAknsSkinChangeHandler( *this, aPriority );
if( !iMemberData->iHandler )
{
AKNS_TRACE_ERROR("RAknsSrvSession::Connect NO MEMORY FOR HANDLER");
delete iMemberData;
iMemberData = NULL;
return KErrNoMemory;
}
CActiveScheduler::Add( iMemberData->iHandler );
iMemberData->iHandler->SetActive();
// Set the notify handler also on the server side;
SendReceive( EAknSkinSrvSetNotifyHandler, TIpcArgs( iMemberData->iHandler) );
EventHandled();
}
AKNS_TRACE_INFO("RAknsSrvSession::Connect COMPLETED");
// Everything went ok if we managed to get here.
return KErrNone;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Close
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::Close()
{
if ( iMemberData && iMemberData->iHandler )
{
iMemberData->iHandler->Cancel();
delete iMemberData->iHandler;
iMemberData->iHandler = NULL;
}
RSessionBase::Close();
if (iMemberData)
{
delete iMemberData;
iMemberData = NULL;
}
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::EnableSkinChangeNotify
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::EnableSkinChangeNotify()
{
SendReceive( EAknSkinSrvEnableNotifySkinChange , TIpcArgs( TIpcArgs::ENothing) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::DisableSkinChangeNotify
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::DisableSkinChangeNotify()
{
SendReceive( EAknSkinSrvDisableNotifySkinChange, TIpcArgs( TIpcArgs::ENothing) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::ClientError
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::ClientError(TInt aErrorCode)
{
AKNS_TRACE_ERROR("RAknsSrvSession::ClientError");
SendReceive(EAknSkinSrvClientError, TIpcArgs( aErrorCode ) );
AKNS_TRACE_INFO("RAknsSrvSession::ClientError COMPLETED");
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::SetAllDefinitionSets
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::SetAllDefinitionSets( const TAknsPkgID aPID )
{
AKNS_TRACE_INFO2("RAknsSrvSession::SetAllDefinitionSets %i %i", aPID.iNumber, aPID.iTimestamp);
TInt freeRAM = 0;
HAL::Get(HALData::EMemoryRAMFree, freeRAM);
if ( freeRAM < KAknSkinSrvFreeRAMNeeded )
{
return KErrNoMemory;
}
return SendReceive( EAknSkinSrvSetAllItemDefSets,
TIpcArgs( aPID.iNumber, aPID.iTimestamp) );
} //lint !e1746 TUid is a single word
// -----------------------------------------------------------------------------
// RAknsSrvSession::EnumerateSkinPackages
// -----------------------------------------------------------------------------
//
EXPORT_C CArrayPtr<CAknsSrvSkinInformationPkg>*
RAknsSrvSession::EnumerateSkinPackagesL(
TAknSkinSrvSkinPackageLocation aLocation )
{
CArrayPtrFlat<CAknsSrvSkinInformationPkg>* array =
new (ELeave) CArrayPtrFlat<CAknsSrvSkinInformationPkg>(5);
CleanupStack::PushL( TCleanupItem(
AknsSrvCArrayPtrCAknsSrvSkinInformationPkgCleanup, array ) );
TPckgBuf<TInt> pkgCountPack;
SendReceive( EAknSkinSrvEnumeratePackages, TIpcArgs(&pkgCountPack, aLocation));
TInt pkgCount = pkgCountPack();
if (pkgCount <= 0)
{
CleanupStack::Pop( array );
return array;
}
if ( ( pkgCount*sizeof(TAknsSrvSkinInfoPkg) ) > KMaxTInt )
{
CleanupStack::Pop( array );
return array;
}
HBufC8* packages = HBufC8::NewLC(pkgCount*sizeof(TAknsSrvSkinInfoPkg));
TPtr8 ptr8 = packages->Des();
User::LeaveIfError(SendReceive( EAknSkinSrvReceivePackages, TIpcArgs(pkgCount, &ptr8)));
for (TInt count = 0; count < pkgCount; count++)
{
TAknsSrvSkinInfoPkg* pkg = (TAknsSrvSkinInfoPkg*)&(ptr8[count*sizeof(TAknsSrvSkinInfoPkg)]);
CAknsSrvSkinInformationPkg* pack = CAknsSrvSkinInformationPkg::NewL(
pkg->iPID,
pkg->iColorSchemePID,
pkg->iSkinDirectoryBuf,
pkg->iSkinIniFileDirectoryBuf,
pkg->iSkinNameBuf,
pkg->iIdleStateWallPaperImageName,
KNullDesC,
pkg->iFullName,
pkg->iIdleBgImageIndex,
0,
pkg->iIsDeletable,
pkg->iIsCopyable,
EFalse,
pkg->iProtectionType,
pkg->iCorrupted,
pkg->iSupportAnimBg
);
CleanupStack::PushL(pack);
array->AppendL(pack);
CleanupStack::Pop(pack);
}
CleanupStack::PopAndDestroy( packages );
CleanupStack::Pop( array );
AKNS_TRACE_INFO1("RAknsSrvSession::EnumerateSkinPackagesL COMPLETED %i",
array->Count() );
return array;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::CreateChunkLookupL
// -----------------------------------------------------------------------------
//
EXPORT_C CAknsSrvChunkLookup* RAknsSrvSession::CreateChunkLookupL()
{
CAknsSrvChunkLookup* chunklookup = CAknsSrvChunkLookup::NewL();
return chunklookup;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Version
// -----------------------------------------------------------------------------
//
TVersion RAknsSrvSession::Version() const
{
// client side version is set same as the server side version here, since
// both are implemented in the same DLL
return TVersion( KAknSkinSrvMajorVersionNumber,
KAknSkinSrvMinorVersionNumber, KAknSkinSrvBuildVersionNumber );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::SetIdleWallPaper
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::SetIdleWallpaper( const TDesC& aFilename )
{
TInt freeRAM = 0;
HAL::Get(HALData::EMemoryRAMFree, freeRAM);
if ( freeRAM < KAknSkinSrvFreeRAMNeeded )
{
return KErrNoMemory;
}
return SendReceive( EAknSkinSrvSetIdleWallPaper,
TIpcArgs( &aFilename, aFilename.Length() ) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::StoreScalableGraphics(const TAknsItemID& aIID,
const TInt aType, const TSize& aLayoutSize, const CFbsBitmap* aBmp,
const CFbsBitmap* aMask, TBool aMorphing)
{
TAknsSrvLayoutInfo layoutInfo;
layoutInfo.iLayoutType = aType;
layoutInfo.iLayoutSize = aLayoutSize;
TPckgC<TAknsSrvLayoutInfo> layoutInfoPack( layoutInfo );
TInt bmphandle = 0;
TInt mskhandle = 0;
if (aBmp)
{
bmphandle = aBmp->Handle();
}
else
{
return KErrArgument;
}
if (aMask)
{
mskhandle = aMask->Handle();
}
TPckgC<TAknsItemID> iidPack( aIID );
if (aMorphing)
{
return SendReceive( EAknSkinSrvStoreMorphingScalableGfx, TIpcArgs(
&iidPack, &layoutInfoPack, bmphandle, mskhandle));
}
else
{
return SendReceive( EAknSkinSrvStoreScalableGfx, TIpcArgs(
&iidPack, &layoutInfoPack, bmphandle, mskhandle));
}
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::ClearScalableGraphics
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::ClearScalableGraphics()
{
return SendReceive( EAknSkinSrvClearScalableGfx, TIpcArgs() );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::DeleteSkin
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::DeleteSkin(
const TAknsPkgID /*aPID*/, TAknSkinSrvSkinPackageLocation /*aLocation*/ )
{
return KErrNotSupported;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::CopySkin
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::CopySkin(
const TAknsPkgID /*aPID*/, TAknSkinSrvSkinPackageLocation /*aSourceLocation*/,
TAknSkinSrvSkinPackageLocation /*aDestLocation*/)
{
return KErrNotSupported;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::OpenBitmapFile
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::OpenBitmapFile( const TDesC& aFilename, TInt &aFileHandle)
{
TPckgBuf<TInt> filehandlePack;
TInt fileserverHandle = SendReceive(
EAknSkinSrvOpenBitmapFile, TIpcArgs(&aFilename, &filehandlePack));
aFileHandle = filehandlePack();
return fileserverHandle;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::OpenInifile
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::OpenInifile(
const TAknsPkgID aPID, TAknSkinSrvSkinPackageLocation aLocation,
TInt& aFilehandle, TBool aWriteToFile)
{
TPckgC<TAknsPkgID> iidPack( aPID );
TPckgBuf<TInt> filehandlePack;
TInt fileserverHandle = SendReceive(
EAknSkinSrvOpenIniFile, TIpcArgs(&iidPack, aLocation, &filehandlePack, aWriteToFile));
aFilehandle = filehandlePack();
return fileserverHandle;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::CopySoundFile
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::CopySoundFile(const TDesC& aSourceFilename, const TDesC& aTargetFilename)
{
return SendReceive(
EAknSkinSrvCopySoundFile, TIpcArgs(&aSourceFilename, &aTargetFilename) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::DecodeWallpaperImageL
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::DecodeWallpaperImageL(
const TDesC& aFilename, const TSize& aTargetSize, CFbsBitmap*& aBitmap, CFbsBitmap*& aMask)
{
TPckgBuf<TInt> bmphandlePack;
TPckgBuf<TInt> mskhandlePack;
TPckgC<TSize> sizePack(aTargetSize);
User::LeaveIfError(
SendReceive(
EAknSkinSrvDecodeWallpaperImage,
TIpcArgs(&aFilename, &sizePack, &bmphandlePack, &mskhandlePack)));
if (aTargetSize == TSize(-1,-1))
{
// 0,0 is used to check if the image is corrupted
return;
}
delete aBitmap;
aBitmap = NULL;
delete aMask;
aMask = NULL;
CFbsBitmap* bitmap = NULL;
CFbsBitmap* mask = NULL;
bitmap = new (ELeave) CFbsBitmap;
CleanupStack::PushL(bitmap);
User::LeaveIfError(bitmap->Duplicate(bmphandlePack()));
if (mskhandlePack())
{
mask = new (ELeave) CFbsBitmap;
CleanupStack::PushL(mask);
User::LeaveIfError(mask->Duplicate(mskhandlePack()));
CleanupStack::Pop(2);
}
else
{
CleanupStack::Pop( bitmap );
}
AknIconConfig::CompressIfPreferred( bitmap, mask );
aBitmap = bitmap;
aMask = mask;
}
EXPORT_C void RAknsSrvSession::AddWallpaperL(const TDesC& aFilename, const TSize& aTargetSize )
{
TPckgC<TSize> sizePack(aTargetSize);
User::LeaveIfError( SendReceive( EAknSkinSrvCacheWallpaperImage,
TIpcArgs(&aFilename, &sizePack)));
return;
}
EXPORT_C CFbsBitmap* RAknsSrvSession::WallpaperImageL( const TDesC& aFilename )
{
TPckgBuf<TInt> bmphandlePack;
TPckgBuf<TInt> mskhandlePack;
CFbsBitmap* bitmap = NULL;
// CWsScreenDevice* screenDevice =
// STATIC_CAST(CWsScreenDevice*, CCoeEnv::Static()->SystemGc().Device());
// CleanupStack::PushL( screenDevice );
// User::LeaveIfError( screenDevice->Construct() );
// TSize currentScreenSize = screenDevice->SizeInPixels();
// TPckgC<TSize> sizePack( currentScreenSize );
//
// CleanupStack::PopAndDestroy( screenDevice );
TRect screen;
AknLayoutUtils::LayoutMetricsRect(
AknLayoutUtils::EScreen, screen );
TPckgC<TSize> sizePack( screen.Size() );
User::LeaveIfError( SendReceive(EAknSkinSrvDecodeWallpaperImage,
TIpcArgs(&aFilename, &sizePack, &bmphandlePack, &mskhandlePack)));
if ( bmphandlePack() )
{
bitmap = new (ELeave) CFbsBitmap;
CleanupStack::PushL(bitmap);
User::LeaveIfError(bitmap->Duplicate(bmphandlePack()));
CleanupStack::Pop( bitmap );
}
return bitmap;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::OpenImageInifile
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::OpenImageInifile( TAknsSrvInifileType aType, TInt& aFilehandle )
{
TPckgBuf<TInt> filehandlePack;
TInt fileserverHandle = SendReceive( EAknSkinSrvOpenImageInifile, TIpcArgs(&filehandlePack, aType));
aFilehandle = filehandlePack();
return fileserverHandle;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::DoWriteInifileL
// -----------------------------------------------------------------------------
//
void RAknsSrvSession::DoWriteInifileL(const CDesCArray& aFilenameArray)
{
TInt fileserverhandle;
TInt filehandle;
fileserverhandle = OpenImageInifile(EAknsSrvInifileSSWP, filehandle);
RFile file;
User::LeaveIfError(file.AdoptFromServer(fileserverhandle, filehandle));
CleanupClosePushL(file);
User::LeaveIfError(file.SetSize(0));
TFileText textFile;
textFile.Set(file);
textFile.Seek(ESeekStart);
for (TInt count = 0; count < aFilenameArray.Count() ; count++)
{
User::LeaveIfError(textFile.Write(aFilenameArray.MdcaPoint(count)));
}
file.Flush();
CleanupStack::PopAndDestroy(); // file
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::SetSlideSetWallpaper
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::SetSlideSetWallpaper(const CDesCArray& /*aFilenameArray*/)
{
//deprecated for 9.2 page specific wallpaper
return KErrNotSupported;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::FreeUnnecessaryLayoutBitmaps
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::FreeUnnecessaryLayoutBitmaps(TAknsSrcScreenMode aMode)
{
TInt type( aMode );
SendReceive( EAknSkinSrvFreeLayoutBitmaps, TIpcArgs( type ) );
}
EXPORT_C void RAknsSrvSession::RemoveWallpaper( const TDesC& aFilename )
{
SendReceive( EAknSkinSrvFreeDecodedWallpaper, TIpcArgs(&aFilename) );
}
EXPORT_C void RAknsSrvSession::RemoveAllWallpapers( )
{
SendReceive( EAknSkinSrvFreeDecodedWallpaper, TIpcArgs(&KNullDesC) );
}
// -----------------------------------------------------------------------------
// Checks if the appUid has non-skinnable configuration icons.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::CheckIconConfiguration( TUid aAppUid )
{
TPckgC<TUid> uidPack(aAppUid);
return SendReceive( EAknSkinSrvCheckIconConfiguration, TIpcArgs( &uidPack ) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::AcknowledgeSkinChangeNotification
// -----------------------------------------------------------------------------
//
TInt RAknsSrvSession::AcknowledgeSkinChangeNotification()
{
TInt type( EAknsSCHNContentChanged );
return SendReceive( EAknSkinSrvAckNotification, TIpcArgs( type ) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Reserved1
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::Reserved1()
{
return 0;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Reserved2
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::Reserved2()
{
return 0;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Reserved3
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RAknsSrvSession::Reserved3()
{
return 0;
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::Reserved4
// -----------------------------------------------------------------------------
//
EXPORT_C void RAknsSrvSession::Reserved4()
{
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::SendCancel
// -----------------------------------------------------------------------------
//
void RAknsSrvSession::SendCancel()
{
SendReceive(EAknSkinSrvCancel, TIpcArgs( TIpcArgs::ENothing ) );
}
// -----------------------------------------------------------------------------
// RAknsSrvSession::EventHandled
// -----------------------------------------------------------------------------
//
void RAknsSrvSession::EventHandled()
{
SendReceive(EAknSkinSrvNextEvent, TIpcArgs( TIpcArgs::ENothing),
iMemberData->iHandler->iStatus);
}
// End of File