--- /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 <icl\ImageData.h>
+#include <icl\ImageCodecData.h>
+#include <coemain.h>
+#include <PathInfo.h>
+#include <bautils.h>
+#include <apgwgnam.h>// 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<KTimeRecordSize> 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();
+}