--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/skins/AknSkins/srvsrc/AknsSrvUtils.cpp Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,989 @@
+/*
+* Copyright (c) 2003-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 utils class.
+*
+*/
+
+
+// INCLUDE FILES
+#include <f32file.h>
+#include <bautils.h>
+
+#include <e32math.h>
+#include <DRMRights.h>
+
+#include <DRMHelper.h>
+#include <caf/caf.h>
+#include <caf/rightsinfo.h>
+
+#include "AknsSrvUtils.h"
+#include "AknsSrv.h"
+#include "AknsSrvDescriptorFileLayout.h"
+#include <AknsSkinUID.h>
+#include "AknsDriveMaster.h"
+
+
+#include "AknsDebug.h"
+
+#include <centralrepository.h>
+#include <AknSkinsInternalCRKeys.h>
+#include <AknsConstants.h>
+
+// Maximum lenght of uri.
+const TInt KMaxContentUriLength = 256;
+
+// Length of extension (including preceding dot).
+const TInt KExtensionLength = 4;
+
+// Mif-file extension
+_LIT( KAknsSkinSrvMifFileExt, ".mif" );
+
+const TInt KAknsDummySkinPkgID = 0x70000000;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::CheckAHOverrideFlag
+// -----------------------------------------------------------------------------
+//
+TBool AknsSrvUtils::CheckAHOverrideFlagL( CAknsSrvFileBuffer& aFile )
+ {
+ TUint8 ahflag = GetUInt8L( aFile, EAknsSrvDFOSkinSkinType );
+
+ if ( (ahflag&2) !=0 )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::SearchSkinsL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::SearchSkinsL(
+ RFs& aRfs, const TDesC& aBasePath, const TDesC& aDirName,
+ CDesCArray* aSkinFiles )
+ {
+ SearchSkinsL( aRfs, aBasePath, aDirName, KSKNPostFix, aSkinFiles );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::SearchDirectoriesL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::SearchDirectoriesL(
+ RFs& aRFs, const TDesC& aPath, CDesCArray* aSkinFiles )
+ {
+ SearchDirectoriesL( aRFs, aPath, KSKNPostFix, aSkinFiles );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetSkinPIDL
+// -----------------------------------------------------------------------------
+//
+TAknsPkgID AknsSrvUtils::GetSkinPIDL(CAknsSrvFileBuffer& aFile)
+ {
+ TInt number = GetInt32L( aFile, EAknsSrvDFOSkinSkinPID1 );
+ TInt timestamp = GetInt32L( aFile, EAknsSrvDFOSkinSkinPID2 );
+
+ TAknsPkgID pid;
+ pid.Set( timestamp, number );
+ return pid;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::BuildSkinInfoPackagesL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::BuildSkinInfoPackagesL(
+ CArrayPtr<TAknsSrvSkinInfoPkg>* aSkinInfo, CDesCArray* aSkinArray,
+ RFs& aFileSession, CDRMHelper& aDrmHelper )
+ {
+ AKNS_TRACE_INFO("AknsSrvUtils::BuildSkinInfoPackagesL BEGIN" );
+ TAknsSrvSkinInfoPkg* infopkg = NULL;
+
+ // Read default skin PID.
+ CRepository* repository = CRepository::NewLC( KCRUidPersonalisation );
+ TInt value = 0;
+ TBuf<32> buf;
+ TAknsPkgID defaultSkin = KAknsNullPkgID;
+
+ TInt err = repository->Get( KPslnDefaultSkinUID, buf );
+ if ( err != KErrNone || buf.Length() < 8 )
+ {
+ err = repository->Get( KPslnDefaultSkinID, value );
+ if( err == KErrNone )
+ {
+ defaultSkin.Set( TUid::Uid( value ) );
+ }
+ }
+ else
+ {
+ TInt bufLength = buf.Length();
+ // If its 8 characters long, its UID.
+ // PIDs are 16 characters (8 ID + 8 timestamp)
+ if ( bufLength == 8 )
+ {
+ // Let's try to set it directly as Hex.
+ TLex hexLex( buf );
+ TUint pid;
+ err = hexLex.Val( pid, EHex );
+ if (!err)
+ {
+ // UIDs have no timestamp.
+ defaultSkin.Set( 0, pid );
+ }
+ }
+ else
+ {
+ // The skin PID is set in CenRep in format <PID1><PID2> and
+ // values are in hex.
+ TLex lex ( buf.Left( 8 ) );
+ TLex lex2 ( buf.Right( 8 ) );
+ TUint pid;
+ TUint timeStamp;
+ err = lex.Val( pid, EHex );
+ if ( !err )
+ {
+ err = lex2.Val( timeStamp, EHex );
+ }
+ if ( !err )
+ {
+ defaultSkin.Set( timeStamp, pid );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( repository );
+
+ for( TInt skincount=0; skincount<aSkinArray->Count(); skincount++ )
+ {
+ TRAPD( err2, (infopkg=BuildSkinInfoPackageL(
+ aSkinArray->MdcaPoint(skincount), aDrmHelper, aFileSession ) ) );
+ TBool fabricated = EFalse;
+
+ if( err2 != KErrNone )
+ {
+ // Fabricate skin information, since the array must contain
+ // items for broken skins as well (to ensure that they can
+ // be deleted).
+ TInt index = aSkinArray->MdcaPoint(skincount).LocateReverse('\\');
+ TPtrC filedir;
+ filedir.Set( aSkinArray->MdcaPoint(skincount).Left(index) );
+ TPtrC filename;
+ filename.Set( aSkinArray->MdcaPoint(skincount).Mid(index+1) );
+
+ infopkg = new (ELeave) TAknsSrvSkinInfoPkg;
+ infopkg->iPID = KAknsNullPkgID;
+ infopkg->iColorSchemePID = KAknsPIDColorBlue;
+ infopkg->iSkinDirectoryBuf = filedir;
+ infopkg->iSkinIniFileDirectoryBuf = filedir;
+ infopkg->iSkinNameBuf = filename;
+ infopkg->iIdleStateWallPaperImageName = KNullDesC;
+ infopkg->iFullName = KNullDesC;
+ infopkg->iIsCopyable = EFalse;
+ infopkg->iIsDeletable = ETrue;
+ infopkg->iIdleBgImageIndex = 0;
+ infopkg->iProtectionType = EAknsSrvNoProtection;
+ infopkg->iCorrupted = ETrue;
+ fabricated = ETrue;
+ }
+ CleanupStack::PushL( infopkg );
+
+ TBool mifFile = EFalse;
+ TBool alreadyFound = EFalse;
+
+ if( infopkg )
+ {
+ if ( infopkg->iFullName.Length() > 0 )
+ {
+ SkinHasMifFileL( mifFile, aFileSession, infopkg->iFullName );
+ }
+
+ // If no mif-file, assume that skin is corrupted.
+ if ( !mifFile )
+ {
+ infopkg->iCorrupted = ETrue;
+ }
+
+ for( TInt i=0; i<aSkinInfo->Count(); i++ )
+ {
+ if( aSkinInfo->At(i)->iPID == infopkg->iPID )
+ {
+ alreadyFound = ETrue;
+ break;
+ }
+ }
+ }
+
+ if( infopkg && ((!alreadyFound) || fabricated) )
+ {
+ // Add all but default skin.
+ if ( infopkg->iPID != KAknsPIDS60DefaultSkin )
+ {
+ aSkinInfo->AppendL(infopkg);
+ CleanupStack::Pop( infopkg );
+ }
+ // If default skin ID has not been changed, show S60 default skin.
+ else if ( defaultSkin == KAknsNullPkgID &&
+ infopkg->iPID == KAknsPIDS60DefaultSkin )
+ {
+ aSkinInfo->AppendL(infopkg);
+ CleanupStack::Pop( infopkg );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); //infopkg
+ }
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // infopkg
+ }
+ }
+ AKNS_TRACE_INFO("AknsSrvUtils::BuildSkinInfoPackagesL END" );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::IsDrmProtectedL
+// -----------------------------------------------------------------------------
+//
+TBool AknsSrvUtils::IsDrmProtectedL(const TDesC& aFilename)
+ {
+ TBool isProtected(EFalse);
+ TInt value = KErrNone;
+
+ CContent* content = CContent::NewLC( aFilename );
+ User::LeaveIfError( content->GetAttribute( EIsProtected, value ) );
+ if ( value )
+ {
+ isProtected = ETrue;
+ }
+ CleanupStack::PopAndDestroy( content );
+ return isProtected;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::IsDrmProtectedL
+// -----------------------------------------------------------------------------
+//
+TBool AknsSrvUtils::IsDrmProtectedL(RFile& aFileHandle)
+ {
+ TBool isProtected(EFalse);
+ TInt value = KErrNone;
+
+ CContent* content = CContent::NewLC( aFileHandle );
+ User::LeaveIfError( content->GetAttribute( EIsProtected, value ) );
+ if ( value )
+ {
+ isProtected = ETrue;
+ }
+ CleanupStack::PopAndDestroy( content );
+ return isProtected;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::BuildSkinInfoPackageL
+// -----------------------------------------------------------------------------
+//
+TAknsSrvSkinInfoPkg* AknsSrvUtils::BuildSkinInfoPackageL(
+ const TDesC& aFilename, CDRMHelper& aDrmHelper, RFs& aFileSession )
+ {
+ TAknsSrvSkinInfoPkg* infopkg = NULL;
+ TAknsSkinSrvSkinProtectionType protectionType = EAknsSrvNoProtection;
+ TBool isProtected(EFalse);
+
+ TChar driveLetter = aFilename[0];
+ TInt driveNumber;
+ User::LeaveIfError(aFileSession.CharToDrive(driveLetter, driveNumber));
+ User::LeaveIfError(aFileSession.ShareProtected());
+
+ TInt err = aFileSession.CreatePrivatePath(driveNumber);
+
+ if (err!=KErrNone && err!=KErrAlreadyExists)
+ {
+ User::Leave(err);
+ }
+
+ User::LeaveIfError(aFileSession.SetSessionToPrivate(driveNumber));
+
+ RFile file;
+ User::LeaveIfError(file.Open(aFileSession,aFilename, EFileRead | EFileShareReadersOnly));
+ CleanupClosePushL(file); // 1
+
+ // Files on ROM are not DRM protected
+ if (aFilename[0] != 'Z')
+ {
+ isProtected = IsDrmProtectedL(file);
+ if (isProtected)
+ {
+ // If protection is indicated, by default set it on.
+ protectionType = EAknsSrvProtected;
+
+ TBool expired = EFalse;
+ TBool sendAllowed = EFalse; //not needed
+ CDRMHelperRightsConstraints* playDrmHlpCons = NULL;
+ CDRMHelperRightsConstraints* dispDrmHlpCons = NULL;
+ CDRMHelperRightsConstraints* execDrmHlpCons = NULL;
+ CDRMHelperRightsConstraints* printDrmHlpCons = NULL;
+ TRAPD( drmErr, aDrmHelper.GetRightsDetailsL(
+ aFilename, ContentAccess::EView, expired, sendAllowed,
+ playDrmHlpCons, dispDrmHlpCons, execDrmHlpCons, printDrmHlpCons ) );
+ // DrmHelper leaves if the content is protected, but there are rights.
+
+ if ( drmErr == KErrCANoRights )
+ {
+ protectionType = EAknsSrvNoRights;
+ }
+ else if ( drmErr == KErrArgument )
+ {
+ protectionType = EAknsSrvNoProtection;
+ }
+ // Delete not needed constraints.
+ delete printDrmHlpCons;
+ delete execDrmHlpCons;
+ delete playDrmHlpCons;
+ CleanupStack::PushL( dispDrmHlpCons );
+ // Check expiration. If expired and no rights => expired.
+ if ( expired && !dispDrmHlpCons )
+ {
+ protectionType = EAknsSrvExpiredRights;
+ }
+ // If expired, but there are rights => future rights.
+ if ( expired && dispDrmHlpCons )
+ {
+ protectionType = EAknsSrvFutureRights;
+ }
+ if ( dispDrmHlpCons )
+ {
+ TUint32 counter = 0;
+ TUint32 origCounter = 0;
+ TRAP( drmErr, dispDrmHlpCons->GetCountersL( counter, origCounter ) );
+ // No counters
+ if ( drmErr == KErrNotFound )
+ {
+ protectionType = EAknsSrvProtected;
+ }
+ else
+ {
+ protectionType = EAknsSrvCountBased;
+ }
+ }
+ CleanupStack::PopAndDestroy( dispDrmHlpCons );
+ }
+ else
+ {
+ protectionType = EAknsSrvNoProtection;
+ }
+ }
+ CAknsSrvFileBuffer* fileBuf = NULL;
+ if (!isProtected) // The file is not protected, open it normally
+ {
+ fileBuf = CAknsSrvFileBuffer::NewL( file );
+ CleanupStack::PushL( fileBuf ); // 2
+ }
+ else // The file is protected, open it ignoring the rights..
+ {
+ TInt error = aDrmHelper.ConsumeFile2(
+ file, EInstall, CDRMHelper::EStart );
+ if ( error == KErrCANoRights ||
+ protectionType == EAknsSrvNoRights ||
+ protectionType == EAknsSrvExpiredRights )
+ {
+ // Rights object deleted, bake up something
+ // sensible
+ TInt index = aFilename.LocateReverse('\\');
+ TPtrC filedir;
+ filedir.Set( aFilename.Left(index) );
+ TPtrC filename;
+ filename.Set( aFilename.Mid(index+1) );
+ infopkg = new (ELeave) TAknsSrvSkinInfoPkg;
+ //Create a Random id for DRM Expired Skin
+ TAknsPkgID dummyPID = { KAknsDummySkinPkgID + (Math::Random()>>4), 0 };
+ infopkg->iPID = dummyPID;
+ infopkg->iColorSchemePID = KAknsPIDColorBlue;
+ infopkg->iSkinDirectoryBuf = filedir;
+ infopkg->iSkinIniFileDirectoryBuf = filedir;
+ infopkg->iSkinNameBuf = filename;
+ infopkg->iIdleStateWallPaperImageName = KNullDesC;
+ infopkg->iFullName = aFilename;
+ infopkg->iIsCopyable = EFalse;
+ infopkg->iIsDeletable = ETrue;
+ infopkg->iIdleBgImageIndex = 0;
+ infopkg->iProtectionType = protectionType;
+ infopkg->iCorrupted = EFalse;
+ CleanupStack::PopAndDestroy( ); // file
+ return infopkg;
+ }
+ else if ( error != KErrNone )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ fileBuf = CAknsSrvFileBuffer::NewL( file);
+ CleanupStack::PushL( fileBuf ); // 2
+ }
+ if( CheckAHOverrideFlagL( *fileBuf ) )
+ {
+ // Do not build package for A&H override skins
+ CleanupStack::PopAndDestroy(2); //fileBuf, file
+ return NULL;
+ }
+
+ TAknsPkgID pid;
+ pid.Set( GetSkinPIDL( *fileBuf ) );
+
+ TInt index = aFilename.LocateReverse('\\');
+ TPtrC filedir;
+ filedir.Set( aFilename.Left(index));
+
+ TInt idlebmpindex(0);
+ HBufC* idlewallpaperbmpname = KAknsSkinSrvEmptyString().AllocL();
+ CleanupStack::PushL(idlewallpaperbmpname); // 3
+
+
+ HBufC* name = AknsSrvUtils::GetSkinNameL( *fileBuf );
+ CleanupStack::PushL(name); // 4
+
+ infopkg = new (ELeave) TAknsSrvSkinInfoPkg;
+ infopkg->iPID = pid;
+ infopkg->iColorSchemePID = KAknsPIDColorBlue;
+ infopkg->iSkinDirectoryBuf = filedir;
+ infopkg->iSkinNameBuf = *name;
+ infopkg->iIdleStateWallPaperImageName = *idlewallpaperbmpname;
+ infopkg->iFullName = aFilename;
+ infopkg->iIsCopyable = EFalse;
+ infopkg->iIsDeletable = EFalse;
+ infopkg->iIdleBgImageIndex = idlebmpindex;
+ infopkg->iCorrupted = EFalse;
+ infopkg->iSupportAnimBg = AnimBackgroundSupportL( *fileBuf );
+
+ if ( filedir.LocateF('Z') == 0)
+ {
+ TPath inifiledir;
+ inifiledir.Append(filedir);
+
+ TPath defaultDrive;
+ CAknsSrvDriveMaster::GetDefaultDrive( DriveInfo::EDefaultSystem, defaultDrive );
+ inifiledir.Replace( 0, 3, defaultDrive );
+
+ infopkg->iSkinIniFileDirectoryBuf = inifiledir;
+ infopkg->iProtectionType = EAknsSrvNoProtection;
+ }
+ else
+ {
+ infopkg->iSkinIniFileDirectoryBuf = filedir;
+ infopkg->iProtectionType = protectionType;
+ }
+
+ CleanupStack::PopAndDestroy( 2, idlewallpaperbmpname );
+ if (isProtected)
+ {
+ aDrmHelper.ConsumeFile2(
+ file, EInstall, CDRMHelper::EFinish );
+ }
+ CleanupStack::PopAndDestroy(2); // file, fileBuf
+ return infopkg;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::AnimBackgroundSupportL
+// -----------------------------------------------------------------------------
+//
+TBool AknsSrvUtils::AnimBackgroundSupportL(CAknsSrvFileBuffer& aFile)
+ {
+ TInt32 numberofchunks = GetInt32L( aFile, EAknsSrvDFOSkinChunksN );
+ TInt32 chunksize = 0;
+ TUint16 chunktype = 0;
+ TInt totaloffset = EAknsSrvDFOSkinContent;
+ for (TInt count = 0;count< numberofchunks;count++)
+ {
+ chunksize = GetInt32L( aFile, totaloffset+EAknsSrvDFOCommonLength );
+ chunktype = GetUInt16L( aFile, totaloffset+EAknsSrvDFOCommonType );
+ if( chunktype == EAknsSkinDescSkinDescClass )
+ {
+ TInt chunkoffset = totaloffset;
+ TInt32 chunkcount = GetInt32L( aFile,chunkoffset+EAknsSrvDFOClassChunksN );
+
+ chunkoffset += EAknsSrvDFOClassContent;
+ for (TInt count = 0;count < chunkcount;count++)
+ {
+ TInt32 chunklen = GetInt32L( aFile,chunkoffset+EAknsSrvDFOCommonLength );
+ TInt16 chunktype = GetUInt16L( aFile,chunkoffset+EAknsSrvDFOCommonType );
+ if ( chunktype == EAknsSkinDescSkinDescStringItemDef )
+ {
+ TInt32 major = GetInt32L( aFile,chunkoffset+EAknsSrvDFOStringMajor );
+ TInt32 minor = GetInt32L( aFile,chunkoffset+EAknsSrvDFOStringMinor );
+ if ( major == EAknsMajorProperty &&
+ minor == EAknsMinorPropertyAnimBgParam )
+ {
+ return ETrue;
+ }
+ }
+ chunkoffset += chunklen;
+ if( GetUInt8L( aFile, chunkoffset-1 ) != 0xf5 )
+ {
+ return EFalse;
+ }
+ }
+ }
+ totaloffset+=chunksize;
+ if( AknsSrvUtils::GetUInt8L( aFile, totaloffset-1 ) != 0xf5 )
+ {
+ return EFalse;
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetSkinFileNameL
+// -----------------------------------------------------------------------------
+//
+HBufC* AknsSrvUtils::GetSkinFileNameL(
+ const TDesC& aPath, const TAknsPkgID aPID, RFs& aFileSession )
+ {
+ AKNS_TRACE_INFO("CAknsSrvUtils::GetSkinFilename ENTERED");
+ HBufC* filename = NULL;
+
+ CDesC16ArrayFlat* skinfiles = new (ELeave) CDesC16ArrayFlat(5);
+ CleanupStack::PushL(skinfiles);
+
+ TPath skindir;
+ skindir.AppendNumFixedWidthUC( aPID.iNumber, EHex, 8 );
+ if( !aPID.IsUid() )
+ {
+ skindir.AppendNumFixedWidthUC( aPID.iTimestamp, EHex, 8 );
+ }
+
+ // No leave here, since path may be missing on some drives
+ TRAPD( err, SearchSkinsL(aFileSession, aPath, skindir, skinfiles ) );
+ if( err )
+ {
+ AKNS_TRACE_ERROR1("CAknsSrvUtils::GetSkinFilename SearchSkinsL FAILED %d", err);
+ CleanupStack::PopAndDestroy( skinfiles );
+ return NULL;
+ }
+
+ if (skinfiles->Count() > 0)
+ {
+ // pickup the first file
+ filename = (skinfiles->MdcaPoint(0)).AllocL();
+ }
+ CleanupStack::Pop( skinfiles );
+ skinfiles->Reset();
+ delete skinfiles;
+ return filename;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::ReadSkinDescL
+// -----------------------------------------------------------------------------
+//
+TUint8* AknsSrvUtils::ReadSkinDescL(
+ CAknsSrvFileBuffer& aFile, const TUint aOffset, const TUint aCount )
+ {
+ TUint8* buff = new (ELeave) TUint8[aCount];
+ CleanupStack::PushL( buff );
+ for( TUint i=0; i<aCount; i++ )
+ {
+ buff[i] = GetUInt8L( aFile, aOffset+i );
+ }
+ CleanupStack::Pop( buff );
+ return buff;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetInt32L
+// -----------------------------------------------------------------------------
+//
+TInt32 AknsSrvUtils::GetInt32L(CAknsSrvFileBuffer& aFile, const TUint aOffset)
+ {
+ return aFile.GetInt32L( aOffset );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetUInt16L
+// -----------------------------------------------------------------------------
+//
+TUint16 AknsSrvUtils::GetUInt16L(CAknsSrvFileBuffer& aFile, const TUint aOffset)
+ {
+ return aFile.GetUint16L( aOffset );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetInt16L
+// -----------------------------------------------------------------------------
+//
+TInt16 AknsSrvUtils::GetInt16L(CAknsSrvFileBuffer& aFile, const TUint aOffset)
+ {
+ return aFile.GetInt16L( aOffset );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetUInt8L
+// -----------------------------------------------------------------------------
+//
+TUint8 AknsSrvUtils::GetUInt8L(CAknsSrvFileBuffer& aFile, const TUint aOffset)
+ {
+ return aFile.GetUint8L( aOffset );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetSkinNameL
+// -----------------------------------------------------------------------------
+//
+HBufC* AknsSrvUtils::GetSkinNameL(CAknsSrvFileBuffer& aFile)
+ {
+ TInt32 numberofchunks =
+ GetInt32L( aFile, EAknsSrvDFOSkinChunksN );
+ TInt32 chunksize = 0;
+ TInt offset = EAknsSrvDFOSkinContent;
+ TUint16 chunktype = 0;
+ TUint16 language = 0;
+ HBufC* name = NULL;
+
+ TLanguage bestfound = ELangOther; // Currently the best match
+ TLanguage phonelang = User::Language();
+ for (TInt count = 0;count< numberofchunks;count++)
+ {
+ chunksize = GetInt32L( aFile, offset+EAknsSrvDFOCommonLength );
+ chunktype = GetUInt16L( aFile, offset+EAknsSrvDFOCommonType );
+ if( chunktype == EAknsSkinDescName )
+ {
+ language = GetUInt16L( aFile, offset+EAknsSrvDFONameLanguage );
+ if ( (bestfound == ELangOther) ||
+ (language == ELangEnglish) ||
+ (language == phonelang) )
+ {
+ if (name)
+ {
+ CleanupStack::Pop(name);
+ delete name;
+ }
+ TUint16 namelen = GetUInt16L(
+ aFile, offset+EAknsSrvDFONameNameLen );
+ TUint8* namebuf = ReadSkinDescL(
+ aFile, offset+EAknsSrvDFONameName, 2*namelen );
+ TBuf<128> buf;
+ // We only want 128 leftmost characters from the skin name
+ // and the rest is discarded...
+ if( namelen>127 )
+ {
+ namelen = 127;
+ }
+ buf.Append( reinterpret_cast<TUint16*>(namebuf), namelen );
+ buf.ZeroTerminate();
+ delete [] namebuf;
+ name = buf.AllocL();
+ CleanupStack::PushL(name);
+ bestfound = static_cast<TLanguage>(language);
+ if (bestfound == phonelang)
+ {
+ break; // Found the correct language, break here...
+ }
+ }
+ }
+ offset+=chunksize;
+ if( AknsSrvUtils::GetUInt8L( aFile, offset-1 ) != 0xf5 )
+ {
+ AKNS_TRACE_ERROR("AknsSrvUtils::GetSkinNameL CORRUPTED FILE!");
+ User::Leave( KErrCorrupt );
+ }
+ }
+ if (name)
+ {
+ CleanupStack::Pop(name);
+ }
+ return name;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::IsFile
+// -----------------------------------------------------------------------------
+//
+TBool AknsSrvUtils::IsFile( RFs& aFileSession, const TDesC& aFilename )
+ {
+ TBool result = EFalse;
+ {
+ TUint attValue;
+ if( aFileSession.Att( aFilename, attValue ) == KErrNone )
+ {
+ result = ETrue;
+ }
+ }
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::SearchSkinsL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::SearchSkinsL(
+ RFs& aRfs, const TDesC& aBasePath, const TDesC& aDirName,
+ const TDesC& aExtension, CDesCArray* aSkinFiles )
+ {
+ CDir* dir = NULL;
+ TPath path;
+ path.Append(aBasePath);
+ path.Append(aDirName);
+ path.Append( aExtension );
+
+ TFileName filename;
+ User::LeaveIfError(
+ aRfs.GetDir( path, KEntryAttMaskSupported, ESortByName, dir) );
+
+ CleanupStack::PushL( dir );
+
+ TInt filecount = dir->Count();
+ AKNS_TRACE_INFO1("AknsSrvUtils::SearchSkinsL filecount = %d", filecount );
+
+ for (TInt file = 0;file<filecount;file++)
+ {
+ filename.Copy(aBasePath);
+ filename.Append(aDirName);
+ filename.Append('\\');
+ filename.Append((*dir)[file].iName);
+
+ aSkinFiles->AppendL(filename);
+ }
+ AKNS_TRACE_INFO1("AknsSrvUtils::SearchSkinsL skinFiles = %d", aSkinFiles->Count() );
+ CleanupStack::PopAndDestroy( dir );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::SearchDirectoriesL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::SearchDirectoriesL(
+ RFs& aRfs, const TDesC& aPath, const TDesC& aExtension, CDesCArray* aSkinFiles )
+ {
+ // First read the directory containing skins
+ TInt dircount;
+ CDir* dir;
+
+ // We don't want to leave here, the path to be searched might not be
+ // present on all drives....
+ TInt err = aRfs.GetDir( aPath,
+ KEntryAttMatchExclusive |KEntryAttMatchMask |KEntryAttDir,
+ ESortByName,dir );
+ if (err)
+ {
+ return;
+ }
+
+ CleanupStack::PushL(dir);
+
+ dircount = dir->Count();
+
+ for (TInt direntry = 0;direntry<dircount;direntry++)
+ {
+ SearchSkinsL(aRfs, aPath, (*dir)[direntry].iName, aExtension, aSkinFiles);
+ }
+ CleanupStack::PopAndDestroy( dir );
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetSkinFileNameL
+// -----------------------------------------------------------------------------
+//
+HBufC* AknsSrvUtils::GetSkinFileNameL(
+ CAknsSrvDriveMaster& aDriveMaster,
+ const TAknsPkgID aPID,
+ RFs& aFileSession,
+ CAknsSrvDriveMaster::TAknsSrvSkinDriveList aDriveType )
+ {
+ HBufC* skinFileName = NULL;
+ TFileName path;
+ TInt driveCount = aDriveMaster.GetNumberOfDrives( aDriveType );
+ TInt index = 0;
+ for ( ; index < driveCount; index++ )
+ {
+ aDriveMaster.SkinDirectoryOnDrive(
+ aDriveType, index, path );
+ skinFileName = GetSkinFileNameL( path, aPID, aFileSession );
+ if ( skinFileName )
+ {
+ // break the loop when first matching skin file found.
+ index = driveCount;
+ }
+ }
+ return skinFileName;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetContentUriFromFileL
+// -----------------------------------------------------------------------------
+//
+HBufC8* AknsSrvUtils::GetContentUriFromFileL( const TDesC& aFilename )
+ {
+ HBufC8* contenturi = NULL;
+ CContent* content = CContent::NewLC( aFilename );
+
+ HBufC* contentUri = HBufC::NewLC( KMaxContentUriLength );
+ TPtr tempPtr = contentUri->Des();
+ // "EContentID" has the "content uri" we want. Not "EContentURI".
+ TInt err = content->GetStringAttribute( ContentAccess::EContentID, tempPtr );
+ if ( !err )
+ {
+ // Convert to 8-bit string
+ contenturi = HBufC8::NewL( contentUri->Length() );
+ contenturi->Des().Copy( *contentUri );
+ }
+ CleanupStack::PopAndDestroy( 2, content ); // content, contentUri
+ return contenturi;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::GetProtectionTypeL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::GetProtectionTypeL(
+ const TDesC& aFilename,
+ TAknsSkinSrvSkinProtectionType& aProtectionType )
+ {
+ CContent* content = CContent::NewLC( aFilename );
+ TInt value = KErrNone;
+
+ User::LeaveIfError( content->GetAttribute( ERightsNone, value ) );
+ if ( value )
+ {
+ aProtectionType = EAknsSrvNoRights;
+ CleanupStack::PopAndDestroy( content );
+ return;
+ }
+ User::LeaveIfError( content->GetAttribute( ERightsHaveExpired, value ) );
+ if ( value )
+ {
+ aProtectionType = EAknsSrvExpiredRights;
+ CleanupStack::PopAndDestroy( content );
+ return;
+ }
+ User::LeaveIfError( content->GetAttribute( ECanView, value ) );
+ if ( value )
+ {
+ aProtectionType = EAknsSrvProtected;
+ CleanupStack::PopAndDestroy( content );
+ return;
+ }
+ CleanupStack::PopAndDestroy( content );
+ AKNS_TRACE_INFO1("AknsSrvUtils::GetProtectionTypeL - aProtectionType = %d", aProtectionType);
+ return;
+ }
+
+// -----------------------------------------------------------------------------
+// AknsSrvUtils::SkinHasMifFileL
+// -----------------------------------------------------------------------------
+//
+void AknsSrvUtils::SkinHasMifFileL( TBool& aHasMifFile,
+ RFs& aFileSession, const TDesC& aFilename )
+ {
+ aHasMifFile = ETrue;
+ _LIT( KAknsStaticPath, "\\resource\\skins" );
+ TBool parseError = EFalse;
+
+ // No need to make checks for ROM skins.
+ if ( aFilename[0] == 'Z' )
+ {
+ return;
+ }
+
+ HBufC* fileNameBuffer = HBufC::NewL( KMaxFileName );
+ TParsePtrC fileName( aFilename );
+ TPtr bufferPtr = fileNameBuffer->Des();
+
+ // First append drive and static path.
+ if ( fileName.DrivePresent() )
+ {
+ bufferPtr.Append( fileName.Drive() );
+ }
+ else
+ {
+ delete fileNameBuffer;
+ aHasMifFile = EFalse;
+ return;
+ }
+
+ // Append resource path
+ if ( !parseError )
+ {
+ bufferPtr.Append( KAknsStaticPath );
+ }
+
+ if ( fileName.PathPresent() && !parseError )
+ {
+ // Take path without the trailing backslash.
+ TPtrC path = fileName.Path().Left( fileName.Path().Length() - 1 );
+
+ // Locate last backslash.
+ TChar backslash('\\');
+ TInt bsLoc = path.LocateReverse( backslash );
+
+ // Append skin PID to the directory.
+ bufferPtr.Append( fileName.Path().Mid( bsLoc ) );
+
+ if ( fileName.ExtPresent() )
+ {
+ // Last, append filename. Now string is complete.
+ bufferPtr.Append( fileName.NameAndExt() );
+
+ // switch the extension and check for file existance.
+ bufferPtr.Replace(
+ bufferPtr.Length() - KExtensionLength,
+ KExtensionLength,
+ KAknsSkinSrvMifFileExt );
+ if ( !BaflUtils::FileExists( aFileSession, bufferPtr ) )
+ {
+ // Finally, check if this could be old skin - check if
+ // .mif file is in the same directory.
+ bufferPtr.Zero();
+ bufferPtr.Append( fileName.FullName() );
+ bufferPtr.Replace(
+ bufferPtr.Length() - KExtensionLength,
+ KExtensionLength,
+ KAknsSkinSrvMifFileExt );
+ if ( !BaflUtils::FileExists( aFileSession, bufferPtr ) )
+ {
+ // There is no matching .mif-file => leave.
+ delete fileNameBuffer;
+ aHasMifFile = EFalse;
+ return;
+ }
+ }
+
+ // switch back the graphics file extension.
+ bufferPtr.Replace(
+ bufferPtr.Length() - KExtensionLength,
+ KExtensionLength,
+ fileName.Ext() );
+ }
+ else
+ {
+ delete fileNameBuffer;
+ aHasMifFile = EFalse;
+ return;
+ }
+ }
+ else
+ {
+ delete fileNameBuffer;
+ aHasMifFile = EFalse;
+ return;
+ }
+ delete fileNameBuffer;
+ }
+
+// End of File