diff -r 000000000000 -r 3e07fef1e154 testexecfw/useremul/src/ImageCapture.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecfw/useremul/src/ImageCapture.cpp Mon Mar 08 15:03:44 2010 +0800 @@ -0,0 +1,356 @@ +/*------------------------------------------------------------------ + - + * Software Name : UserEmulator + * Version : v4.2.1309 + * + * Copyright (c) 2009 France Telecom. All rights reserved. + * This software is distributed under the License + * "Eclipse Public License - v 1.0" the text of which is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html". + * + * Initial Contributors: + * France Telecom + * + * Contributors: + *------------------------------------------------------------------ + - + * File Name: ImageCapture.cpp + * + * Created: 13/08/2009 + * Author(s): Marcell Kiss, Reshma Sandeep Das + * + * Description: + * Active object implementation for Image capture + *------------------------------------------------------------------ + - + * + */ + +//System Includes +#include +#include +#include +#include +#include +#include // CApaWindowGroupName + +//User Include +#include "ImageCapture.h" + +// ----------------------------------------------------------------------------- +// CImageCapture::NewL +// Creates the instance of class and returns it. +// ----------------------------------------------------------------------------- +// +CImageCapture* CImageCapture::NewL(CSettings& aSettings ,MScreenshotObserver& aObserver, CEikonEnv* aEikonEnv) +{ + CImageCapture* self=CImageCapture::NewLC(aSettings, aObserver, aEikonEnv); + CleanupStack::Pop(); // self; + return self; +} + +// ----------------------------------------------------------------------------- +// CImageCapture::NewLC +// Creates the instance of class and pushes it to the CleanupStack and return +// it. +// ----------------------------------------------------------------------------- +// +CImageCapture* CImageCapture::NewLC(CSettings& aSettings,MScreenshotObserver& aObserver, CEikonEnv* aEikonEnv) +{ + CImageCapture* self = new (ELeave)CImageCapture(aSettings, aObserver, aEikonEnv); + CleanupStack::PushL(self); + self->ConstructL(); + return self; +} +// ----------------------------------------------------------------------------- +// CImageCapture::CImageCapture +// ----------------------------------------------------------------------------- +// +CImageCapture::CImageCapture(CSettings& aSettings,MScreenshotObserver& aObserver, CEikonEnv* aEikonEnv) + : CActive(CActive::EPriorityStandard), + iSettings(aSettings),iBitmap(NULL), + iImageEncoder(NULL), + iObserver(aObserver), + iEEnv(aEikonEnv) +{ +} +// ----------------------------------------------------------------------------- +// CImageCapture::ConstructL +// ----------------------------------------------------------------------------- +// +void CImageCapture::ConstructL() +{ + CActiveScheduler::Add(this); + User::LeaveIfError(iTimer.CreateLocal()); +} +// ----------------------------------------------------------------------------- +// CImageCapture::~CImageCapture +// ----------------------------------------------------------------------------- +// +CImageCapture::~CImageCapture() +{ + Cancel(); + + if (iImageEncoder) + { + delete iImageEncoder; + iImageEncoder = 0; + } + + if(iBitmap) + delete iBitmap; + + iTimer.Close(); + iScreenShotStatus = EIdle; +} +// ------------------------------------------------------------------------------ +// CImageCapture::RunL +// Issues request to save Images and notifies the observer after saving the image +// ------------------------------------------------------------------------------ +// +void CImageCapture::RunL() +{ + switch (iScreenShotStatus) + { + case EIdle: + break; + + case EWaiting: + { + RWsSession& wsSession = iEEnv->WsSession(); + TInt id = wsSession.GetFocusWindowGroup(); + CApaWindowGroupName* lApaWGName; + lApaWGName = CApaWindowGroupName::NewLC(wsSession,id); + + TUid uid = lApaWGName->AppUid(); + + if(uid.operator ==(iAppUid) ) + Fire(ECapturing); + else + FireCapture(1000000); + + CleanupStack::PopAndDestroy(); // lApaWGName + + } + break; + + case ECapturing: + DoCaptureL(); + break; + + + case ESaveComplete: + default: + iObserver.PerformNextAction(1); + delete this; + + } +} +// ----------------------------------------------------------------------------- +// CImageCapture::CaptureL +// ----------------------------------------------------------------------------- +// +void CImageCapture::CaptureL(const TDesC& aName,const TDesC& aXmlFileName, TUid aAppUid) +{ + iFileName.Copy(aName); + iXmlFileName.Copy(aXmlFileName); + iAppUid = aAppUid; + + if(AknLayoutUtils::PenEnabled() && !(aAppUid.iUid ) ) + { + User::After(KWait1); + } + + if(iAppUid.iUid) + Fire(EWaiting); + else + DoCaptureL(); + +} + +// -------------------------------------------------------------------------- +// Captures the screenshot and store it to a buffer. +// -------------------------------------------------------------------------- +void CImageCapture::DoCaptureL() +{ + const CWsScreenDevice* screenDevice = CCoeEnv::Static()->ScreenDevice(); + + TPixelsTwipsAndRotation sizeAndRotation; + screenDevice->GetScreenModeSizeAndRotation( + screenDevice->CurrentScreenMode(), sizeAndRotation); + + if(iBitmap) + delete iBitmap; + iBitmap = NULL; + iBitmap = new (ELeave) CFbsBitmap; + iBitmap->SetSizeInTwips( screenDevice); + User::LeaveIfError( iBitmap->Create( screenDevice->SizeInPixels(),screenDevice->DisplayMode() ) ); + User::LeaveIfError( screenDevice->CopyScreenToBitmap(iBitmap)); + + //save it in a file + DoSaveL(iFileName); + iScreenShotStatus = ESaveComplete; + SetActive(); +} + +// -------------------------------------------------------------------------- +// CImageCapture::Fire +// Fires an event. It means set this active object to active, but completes +// the request immediately. +// -------------------------------------------------------------------------- +void CImageCapture::Fire(TScreenShotStatus aStatus) +{ + iScreenShotStatus = aStatus; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); +} + +// -------------------------------------------------------------------------- +// CImageCapture::FireCapture +// Fires an event after aTime microseconds. +// -------------------------------------------------------------------------- +void CImageCapture::FireCapture(TTimeIntervalMicroSeconds32 aTime) +{ + iScreenShotStatus = EWaiting; + iTimer.After(iStatus, aTime); + if(!IsActive()) + SetActive(); +} + +// -------------------------------------------------------------------------- +// CImageCapture::DoSaveL +// Saves captured screenshot to a file. +// -------------------------------------------------------------------------- +void CImageCapture::DoSaveL(const TDesC& aName) +{ + // Fetch the next available file name. + + HBufC* fileName = GetNextFileNameLC(aName); + CCoeEnv::Static()->FsSession().MkDirAll(*fileName); + + // Set the MIME type + _LIT8(KMimeTypepng,"image/png"); + TPtrC8 mimeType(KMimeTypepng); + + // Prepares the image data (if applied). + CFrameImageData* frameImageData = CFrameImageData::NewL(); + CleanupStack::PushL(frameImageData); + + TPngEncodeData* encodeData = new (ELeave) TPngEncodeData(); + encodeData->iPaletted = EFalse; + encodeData->iColor = ETrue; + encodeData->iBitsPerPixel = 24; + encodeData->iLevel = TPngEncodeData::EBestCompression; + User::LeaveIfError(frameImageData->AppendFrameData(encodeData)); + + // Creates a new encoder and then convert the bitmap. + TRAPD(err, iImageEncoder = CImageEncoder::FileNewL( + CCoeEnv::Static()->FsSession(), *fileName, mimeType)); + if(err == KErrNone) + iImageEncoder->Convert(&iStatus, *iBitmap, frameImageData); + + CleanupStack::PopAndDestroy(frameImageData); // frameImageData + CleanupStack::PopAndDestroy(fileName); // fileName + +} +// -------------------------------------------------------------------------- +// CImageCapture::GetNextFileNameLC +// Get the file name +// -------------------------------------------------------------------------- +HBufC* CImageCapture::GetNextFileNameLC(const TDesC& aName) const +{ + const TInt KNumberLength = 4; // this is to indicate the file numbering, + // e.g. 0001, 0002, etc. + const TInt KMaxIndex = 10000; + const TInt KTimeRecordSize = 512; + + TPtrC filePathPtr; + _LIT(KExtensionpng, ".png"); + _LIT(KSlash,"\\"); + + // Gets the file extension. + TPtrC fileExtension; + fileExtension.Set(KExtensionpng); + + filePathPtr.Set(iSettings.iLogPath); + TInt result = filePathPtr.LocateReverse('\\'); + TPtrC string; + if(result!=KErrNotFound) + string.Set(filePathPtr.Left(result+1)); + + TBuf8 fileName; + fileName.Copy(string); + + if(iXmlFileName.Length()>0) + { + TInt pos=iXmlFileName.LocateReverse('.'); + TPtrC8 ptr; + if(pos!=KErrNotFound) + { + ptr.Set(iXmlFileName.Left(pos)); + fileName.Append(ptr); + } + + fileName.Append(KSlash); + } + + fileName.Append(aName); + HBufC* newFileName = HBufC::NewLC(fileName.Length()+ KNumberLength + fileExtension.Length() + 1); + TPtr newFileNamePtr(newFileName->Des()); + newFileNamePtr.Copy(fileName); + + + // Checks whether aNamexxxx.png already exists on the phone or not. + // This is to prevent over-riding of any existing images with the same name + TBool IsFileExist = ETrue; + TInt index = 1; + HBufC* buffer = HBufC::NewL(newFileNamePtr.MaxLength()); + TPtr bufferPtr(buffer->Des()); + while ((index < KMaxIndex) && (IsFileExist)) + { + bufferPtr.Copy(newFileNamePtr); + bufferPtr.AppendNumFixedWidth(index, EDecimal, KNumberLength); + bufferPtr.Append(fileExtension); + if (BaflUtils::FileExists(CCoeEnv::Static()->FsSession(), *buffer)) + { + index++; + } + else + { + IsFileExist = EFalse; + } + } + delete buffer; + + // If the index exceeds KMaxIndex, then we don't need to format the file name. + if (index >= KMaxIndex) + { + newFileNamePtr.AppendNum(index); + } + else + { + newFileNamePtr.AppendNumFixedWidth(index, EDecimal, KNumberLength); + } + newFileNamePtr.Append(fileExtension); + + // If the index greated then KMaxIndex, then rollback to 1 + + if (index >= KMaxIndex) + { + index = 1; + } + + return newFileName; +} + +void CImageCapture::DoCancel() +{ + if (iImageEncoder) + { + iImageEncoder->Cancel(); + delete iImageEncoder; + iImageEncoder = 0; + } + iTimer.Cancel(); +}