// Copyright (c) 2006-2009 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:
//
/**
@file
@test
@internalComponent - Internal Symbian test code
*/
#include <test/testexecutestepbase.h>
#include <openfont.h>
#include <test/thashreferenceimages.h>
#include <hash.h>
_LIT(KHashIDFormat, "%S_%d_%S_%S_%d");
const TInt KLengthOfHashValue = 256;
const TInt KNumOfDisplayModes = 12;
/* This is a list of display modes used - the parameter passed to the string
creation function is an index into this table
EGray2,
EGray4,
EGray16,
EGray256,
EColor16,
EColor256,
EColor64K,
EColor16M,
EColor4K,
EColor16MU,
EColor16MA,
EColor16MAP
*/
_LIT(KMode0,"EGray2");
_LIT(KMode1,"EGray4");
_LIT(KMode2,"EGray16");
_LIT(KMode3,"EGray256");
_LIT(KMode4,"EColor16");
_LIT(KMode5,"EColor256");
_LIT(KMode6,"EColor64K");
_LIT(KMode7,"EColor16M");
_LIT(KMode8,"EColor4K");
_LIT(KMode9,"EColor16MU");
_LIT(KMode10,"EColor16MA");
_LIT(KMode11,"EColor16MAP");
//Uncomment the line below to save the image of the screen to a mbm file.
//#define SAVEBITMAP
//Note: To updated existing hash values in toutlineandshadow.ini, you need to delete the previous entries along with hashid's in toutlineandshadow.ini and export this ini
//If a existing test case need updating that will change the hash value, then the hash for this test case needs to be removed from the .ini file
//Uncomment the line below to add a new hash value for any test cases that do not already have a hash.
//#define APPEND_NEW_OR_MISSING_HASH_DATA
// Constructor
CTHashReferenceImages::CTHashReferenceImages(CTestStep* aStep, RFbsSession* aFbs):CBase(),iFbs(aFbs),iStep(aStep) { }
EXPORT_C CTHashReferenceImages* CTHashReferenceImages::NewL(CTestStep* aStep, RFbsSession* aFbs, const TDesC *aPath)
{
CTHashReferenceImages* ptr = new (ELeave)CTHashReferenceImages(aStep,aFbs);
CleanupStack::PushL(ptr);
ptr->ConstructL(aPath);
CleanupStack::Pop();
return ptr;
}
void CTHashReferenceImages::ConstructL(const TDesC *aPath)
{
iPath = aPath->AllocL();
}
// Destructor
EXPORT_C CTHashReferenceImages::~CTHashReferenceImages()
{
//nothing is owned by this class, except iPath
delete iPath;
}
/**
Auxilary function should be called only when we need to generate hash values from the screen and returns its hex format.
@param aHexString the output MD5 hash hex string obtained from iBitmapDevice
*/
EXPORT_C void CTHashReferenceImages::GenerateHashAndReturnInHexFormatL(TDes &aHexString)
{
TInt bufLen = CFbsBitmap::ScanLineLength(iBitmapDevice->SizeInPixels().iWidth, iBitmapDevice->DisplayMode());
RBuf8 buff;
buff.CreateL(bufLen);
CleanupClosePushL(buff);
CMD5 *md = CMD5::NewL();
CleanupStack::PushL(md);
for (TPoint pos(0, 0); pos.iY < iBitmapDevice->SizeInPixels().iHeight; pos.iY++)
{
iBitmapDevice->GetScanLine(buff,pos,iBitmapDevice->SizeInPixels().iWidth,iBitmapDevice->DisplayMode());
md->Update(buff);
}
TBuf8<KLengthOfHashValue> hashString;
//md will be reset after calling CMD5::Final() as Final will call Reset.
hashString.Copy(md->Final());
aHexString.Zero();
for(TInt icount=0; icount < hashString.Length(); icount++)
{
aHexString.AppendNumFixedWidth(hashString[icount], EHex, 4);
}
CleanupStack::PopAndDestroy(2, &buff);
}
/**
Auxilary function called to compare generated hash with reference hash and report error if they don't match.
@param aHashIndex holds the hashId.
*/
EXPORT_C void CTHashReferenceImages::CompareHashValuesL(const TDesC& aHashIndex)
{
TBuf<KLengthOfHashValue> hexString;
//Gets the hash value for the current drawings
GenerateHashAndReturnInHexFormatL(hexString);
TPtrC hashFromConfig;
TBool stringFound = iStep->GetStringFromConfig(iStep->ConfigSection(), aHashIndex, hashFromConfig);
if (stringFound)
{
//cannot use the macro //TEST((hashFromConfig.Compare(hexString)) == 0); since iStep needs to be
//referenced
iStep->testBooleanTrue((hashFromConfig.Compare(hexString)) == 0, (TText8*)__FILE__, __LINE__);
}
else
{
#ifdef APPEND_NEW_OR_MISSING_HASH_DATA
//Hash data will be written to ini file if hash id is not found.
//If written the status will be as INI WRITE with the new hash id and value in test log file.
iStep->testBooleanTrue(iStep->WriteStringToConfig(iStep->ConfigSection(), aHashIndex, hexString), (TText8*)__FILE__, __LINE__);
#ifdef SAVEBITMAP
CopyScreenToBitmapL(aHashIndex);
#endif
#else
//Report error in case hash data is missing and APPEND_NEW_OR_MISSING_HASH_DATA is not defined
iStep->testBooleanTrue( 0, (TText8*)__FILE__, __LINE__);
#endif
}
}
/**
Auxilary function called to generate Hash ID String based on the parameters (test case ID, subtest etc...) and returns
HashId looks like:Testcasecame_0010_9_Swiss_EGray2_0 (aTestCase = DrawText_0010 or DrawTextVertical_0010, aSubTestNumber = 9, aFontFaceIndex = Swiss, aDisplayMode = EGray2, aOrientation = 0)
@param aTestCase holds the testcase ID
@param aSubTestNumber holds the subtest number
@param aFontFaceIndex holds the font face index (index used in KFontFace[])
@param aDisplayMode holds the display mode
@param aOrientation holds the orientation number
*/
EXPORT_C HBufC* CTHashReferenceImages::GenerateHashIdStringLC(const TDesC& aTestCase, TInt aSubTestNumber, const TPtrC aName[], TInt aNameIndex,
TInt aDisplayMode, TInt aOrientation)
{
//this is here because at file scope there is uninitialised writable data
const TDesC * KDisplayModeNames[KNumOfDisplayModes] =
{
&KMode0,
&KMode1,
&KMode2,
&KMode3,
&KMode4,
&KMode5,
&KMode6,
&KMode7,
&KMode8,
&KMode9,
&KMode10,
&KMode11,
};
TBuf<KLengthOfHashValue> tempBuffer;
tempBuffer.Format(KHashIDFormat, &aTestCase, aSubTestNumber, &aName[aNameIndex], KDisplayModeNames[aDisplayMode], aOrientation);
return tempBuffer.AllocLC();
}
/**
Auxilary function called to Copy the screen to bitmap (mbm) file.
@param aHashIndex contains hashID. Bitmap is created with the aHashIndex as name
*/
EXPORT_C void CTHashReferenceImages::CopyScreenToBitmapL(const TDesC& aHashIndex)
{
CFbsBitmap *bitmap = new(ELeave)CFbsBitmap();
CleanupStack::PushL(bitmap);
User::LeaveIfError(bitmap->Create(iBitmapDevice->SizeInPixels(), iBitmapDevice->DisplayMode()));
TRect rect = TRect(iBitmapDevice->SizeInPixels());
CFbsBitmapDevice *device=CFbsBitmapDevice::NewL(bitmap);
CleanupStack::PushL(device);
CFbsBitGc *gc;
User::LeaveIfError(device->CreateContext(gc));
gc->BitBlt(TPoint(), iBitmap, rect);
TFileName mbmFile;
mbmFile.Format(iPath->Des(), &aHashIndex);
bitmap->Save(mbmFile);
delete gc;
CleanupStack::PopAndDestroy(2);
}
/*
Auxilary function used to change the referenced member data (ownership is not transferred)
*/
EXPORT_C void CTHashReferenceImages::SetScreenDeviceAndBitmap(CBitmapDevice* aBitmapDevice, CFbsBitmap* aBitmap, CFbsBitGc* aGc )
{
iBitmapDevice = aBitmapDevice;
iBitmap = aBitmap;
iGc = aGc;
}