mmplugins/cameraplugins/source/testcamera/TestCamera.cpp
author Shimizu Satoshi <s_shimizu@isb.co.jp>
Tue, 19 Oct 2010 11:48:59 +0900
branchRCL_3
changeset 64 92a82bc706f7
parent 0 40261b775718
permissions -rw-r--r--
Obtain an image of Webcamera from QEMU and add the Bitmap change display function.

// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Symbian Foundation License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

#include <w32std.h>
#include <ecom/ecom.h>
#include <ecom/implementationproxy.h>
#include <f32file.h> 
#include "TestCamera.h"
#include "test_advanced_settings.h"
#include "test_snapshot.h"
#include "test_image_processing.h"
#include "TestCameraUids.hrh"
#include <ecam.h>

//
// Main stuff
//
// 
// 2nd stage ConstructL calls called by framework
//
CTestCamera* CTestCamera::NewL()
	{
	FileDependencyUtil::CheckFileDependencyL();
   	CTestCamera* self = new(ELeave) CTestCamera;
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

void CTestCamera::Construct2L(MCameraObserver& aObserver,TInt aCameraIndex)
	{
	iObserver = &aObserver;
	iCameraIndex = aCameraIndex;
	}
	
void CTestCamera::Construct2DupL(MCameraObserver& aObserver,TInt aCameraHandle)
	{
	iObserver = &aObserver;
	iCameraHandle = aCameraHandle;
	}

void CTestCamera::ConstructL()	
	{
	
	TInt err;
	TRAP(err, iScreenDev = CFbsScreenDevice::NewL(_L(""),EColor16M));
	if (err == KErrNotSupported)
		{
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(_L(""),EColor64K));
		}
	if (err == KErrNotSupported)
		{
		TRAP(err, iScreenDev = CFbsScreenDevice::NewL(_L(""),EColor4K));
		}
	if (err == KErrNotSupported)
		{
		iScreenDev = CFbsScreenDevice::NewL(_L(""),EColor256);
		}
	else
		{
		User::LeaveIfError(err);		
		}

	User::LeaveIfError(iScreenDev->CreateContext(iScreenGc));
	User::LeaveIfError(iImageSizes.Append( TSize(640, 480) )); // VGA
	User::LeaveIfError(iImageSizes.Append( TSize(160, 120) )); // QQVGA
	iInfo.iNumImageSizesSupported = iImageSizes.Count();
	iStillImageSize = iImageSizes[1]; // Defaults to QQVGA

	User::LeaveIfError(iVideoFrameSizes.Append( TSize(176, 144) )); // QCIF
	User::LeaveIfError(iVideoFrameSizes.Append( TSize(128, 96) ));  // subQCIF
	iInfo.iNumVideoFrameSizesSupported = iVideoFrameSizes.Count();
	User::LeaveIfError(iVideoFrameRates.Append( 10.00 ));
	User::LeaveIfError(iVideoFrameRates.Append(  5.00 ));
	User::LeaveIfError(iVideoFrameRates.Append(  1.00 ));
	iInfo.iNumVideoFrameRatesSupported = iVideoFrameRates.Count();
	iVideoFrameRate = iVideoFrameRates[0];
	// Still image used as view finder source if not defined otherwise
	iStillImage = new(ELeave) CFbsBitmap;
	User::LeaveIfError(iStillImage->Create(iStillImageSize, KViewFinderDisplayMode));
	iStillImageDev = CFbsBitmapDevice::NewL(iStillImage);
	User::LeaveIfError(iStillImageDev->CreateContext(iStillImageGc));
	iStillImageGc->SetPenColor(KRgbBlack);
	iStillImageGc->SetPenSize(TSize(KFrameFeatureBorderThickness, KFrameFeatureBorderThickness));
	iStillImageGc->SetBrushColor(KRgbWhite);
	iStillImageGc->SetFaded(ETrue);
	iVideoPreparedLast = EFalse;
	iTimer = CPeriodic::NewL(CActive::EPriorityHigh);
	}


void CTestCamera::Construct2L(MCameraObserver2& aObserver,TInt aCameraIndex,TInt aPriority)
	{
	iObserver2 = &aObserver;
	iCameraIndex = aCameraIndex;
	iPriority = aPriority;
	}
	
void CTestCamera::Construct2DupL(MCameraObserver2& aObserver,TInt aCameraHandle)
	{
	iObserver2 = &aObserver;
	iCameraHandle = aCameraHandle;
	}
	

CTestCamera::CTestCamera():
	iStillImageFormat(KInitialViewFinderFormat),
	iReserveAsync(CActive::EPriorityStandard),
	iPowerOnAsync(CActive::EPriorityStandard),
	iImageCaptureAsync(CActive::EPriorityStandard),
	iVideoCaptureAsync(CActive::EPriorityStandard),
	iHandleEventAsync(CActive::EPriorityStandard),
	iHandleEvent2Async(CActive::EPriorityStandard),	
	iFrameBuffer1(iVideoFrame1),
	iFrameBuffer2(iVideoFrame2),
	iFrameCameraBuffer1(iVideoFrame1),
	iFrameCameraBuffer2(iVideoFrame2),
	iContrast(0),
	iBrightness(0),
	iImgProcBrightness(0),
	iImgProcContrast(0),
	iVideoCaptureActive(EFalse),
	iImageCaptureActive(EFalse),
	iVideoPreparedLast(EFalse),
	iVideoCapturePrepared(EFalse),
	iImageCapturePrepared(EFalse),
	iECamEvent(KNullUid, KErrNone),
	iECamEvent2(KNullUid, KErrNone, 0),
	iAdvSettingsImpl(NULL),
	iSnapshotImpl(NULL),
	iImgProcImpl(NULL),
	iDriveMode(KDefaultDriveMode),
	iBurstImages(KBurstImages)
	{
	TCallBack reserveCallBack(ReserveCallBack,this);
	iReserveAsync.Set(reserveCallBack);
	TCallBack powerOnCallBack(PowerOnCallBack,this);
	iPowerOnAsync.Set(powerOnCallBack);
	TCallBack imageCaptureCallBack(ImageCaptureCallBack,this);
	iImageCaptureAsync.Set(imageCaptureCallBack);
	TCallBack videoCaptureCallBack(VideoCaptureCallBack,this);
	iVideoCaptureAsync.Set(videoCaptureCallBack);
	TCallBack handleEventCallBack(HandleEventCallBack,this);
	iHandleEventAsync.Set(handleEventCallBack);
	TCallBack handleEvent2CallBack(HandleEvent2CallBack,this);
	iHandleEvent2Async.Set(handleEvent2CallBack);

	iInfo.iHardwareVersion.iMajor = 0;
	iInfo.iHardwareVersion.iMinor = 0;
	iInfo.iHardwareVersion.iBuild = 0;
	iInfo.iSoftwareVersion.iMajor = 0;
	iInfo.iSoftwareVersion.iMinor = 0;
	iInfo.iSoftwareVersion.iBuild = 0;
	iInfo.iOrientation = TCameraInfo::EOrientationOutwards;

	iInfo.iOptionsSupported = 0;
	iInfo.iOptionsSupported |= TCameraInfo::EViewFinderDirectSupported;
	iInfo.iOptionsSupported |= TCameraInfo::EViewFinderBitmapsSupported;
	iInfo.iOptionsSupported |= TCameraInfo::EImageCaptureSupported;
	iInfo.iOptionsSupported |= TCameraInfo::EVideoCaptureSupported;
	iInfo.iOptionsSupported |= TCameraInfo::EContrastSupported;
	iInfo.iOptionsSupported |= TCameraInfo::EBrightnessSupported;
	iInfo.iOptionsSupported |= TCameraInfo::EViewFinderClippingSupported;

	iInfo.iFlashModesSupported = 0; // Bitfield of TFlash values
	iInfo.iExposureModesSupported = 0; // Bitfield of TExposure values
	iInfo.iWhiteBalanceModesSupported = 0; // Bitfield of TWhiteBalance values

	iInfo.iMinZoom = KMinTestCameraZoom;
	// KMinTestCameraZoom is zero or negative
	// note the algorithm for creating of zoom factor
	iInfo.iMinZoomFactor = TReal32(1)/TReal32(1 << -KMinTestCameraZoom);
	iInfo.iMaxZoom = KMaxTestCameraZoom;
	iInfo.iMaxZoomFactor = 1 << KMaxTestCameraZoom;

	iInfo.iMaxDigitalZoom = KMaxTestCameraDigitalZoom;
	iInfo.iMaxDigitalZoomFactor = KMaxTestCameraDigitalZoomFactor;

	iInfo.iImageFormatsSupported = 0;
	iInfo.iImageFormatsSupported |= EFormatFbsBitmapColor4K;
	iInfo.iImageFormatsSupported |= EFormatFbsBitmapColor64K;
	iInfo.iImageFormatsSupported |= EFormatFbsBitmapColor16M;

	iInfo.iVideoFrameFormatsSupported = 0;
	iInfo.iVideoFrameFormatsSupported |= EFormatFbsBitmapColor4K;
	iInfo.iVideoFrameFormatsSupported |= EFormatFbsBitmapColor64K;
	iInfo.iVideoFrameFormatsSupported |= EFormatFbsBitmapColor16M;
	iInfo.iMaxFramesPerBufferSupported = 1;
	iInfo.iMaxBuffersSupported = 2;
	
	iScreenRect = TRect(TPoint(0,0), TPoint(0,0));
	
	iEventError = KErrNone;
	}
	
CTestCamera::~CTestCamera()
	{
	delete iTimer;
	delete iStillImage;
	delete iStillImageGc;
	delete iStillImageDev;
	delete iVideoFrame1;
	delete iVideoFrameGc1;
	delete iVideoFrameDev1;
	delete iVideoFrame2;
	delete iVideoFrameGc2;
	delete iVideoFrameDev2;
	delete iViewFinderBitmapGc;
	delete iViewFinderBitmapDev;
	delete iViewFinderBitmap;
	delete iDSA;
	delete iScreenGc;
	delete iScreenDev;
	delete iGc;
	delete iDev;
	delete iImage;
	delete iAdvSettingsImpl;
	delete iSnapshotImpl;
	delete iImgProcImpl;
	iImageSizes.Reset();
	iVideoFrameSizes.Reset();
	iVideoFrameRates.Reset();
	}

void CTestCamera::CameraInfo(TCameraInfo& aInfo) const
	{
	aInfo = iInfo;
	}

void CTestCamera::Reserve()
	{
	iReserved = ETrue;
	iReserveAsync.CallBack();
	}

void CTestCamera::Release()
	{
	iReserved = EFalse;
	iTimer->Cancel();
	}

void CTestCamera::PowerOn()
	{
	if (!iReserved || iPowerOn)
		{
		iPowerOnAsync.CallBack();
		return;
		}

	iPowerOn = ETrue;
	TCallBack callback(TimerCallBack,this);
	iTimer->Start(0,TInt(TReal32(1000000) / iVideoFrameRate), callback);
	iPowerOnAsync.CallBack();
	}

void CTestCamera::PowerOff()
	{
	iPowerOn = EFalse;
	iTimer->Cancel();
	}

TInt CTestCamera::Handle()
	{
	return 0;
	}

void CTestCamera::SetZoomFactorL(TInt aZoomFactor)
	{
	// it is equivalent to comparing with iInfo members as they are initialised with the same constants
	// if (aZoomFactor < iInfo.iMinZoom || aZoomFactor > iInfo.iMaxZoom)
	if (aZoomFactor < KMinTestCameraZoom || aZoomFactor > KMaxTestCameraZoom)
		{
		User::Leave(KErrNotSupported);	
		}

	iZoom = aZoomFactor;
	}

TInt CTestCamera::ZoomFactor() const
	{
	// default value is 0
	return iZoom;
	}

void CTestCamera::SetDigitalZoomFactorL(TInt aDigitalZoomFactor)
	{
	CheckReserveAndPowerL();
	// it is equivalent to comparing with iInfo member as it is initialised with the same constant
	// if (aDigitalZoomFactor < 0 || aDigitalZoomFactor > iInfo.iMaxDigitalZoom)
	if (aDigitalZoomFactor < 0 || aDigitalZoomFactor > KMaxTestCameraDigitalZoom)
		{
		User::Leave(KErrNotSupported);	
		}

	iDigitalZoom = aDigitalZoomFactor;
	}

TInt CTestCamera::DigitalZoomFactor() const
	{
	// default value is 0
	return iDigitalZoom;
	}

void CTestCamera::SetContrastL(TInt aContrast)
	{
	CheckReserveAndPowerL();

	iContrast = Min(Max(aContrast,-100),100);
	}

TInt CTestCamera::Contrast() const
	{
	return iContrast;
	}

void CTestCamera::SetBrightnessL(TInt aBrightness)
	{
	CheckReserveAndPowerL();

	iBrightness = Min(Max(aBrightness,-100),100);
	}

TInt CTestCamera::Brightness() const
	{
	return iBrightness;
	}

void CTestCamera::SetFlashL(TFlash aFlash)
	{
	CheckReserveAndPowerL();

	if (aFlash != EFlashNone)
		{
		User::Leave(KErrNotSupported);	
		}
	}

CCamera::TFlash CTestCamera::Flash() const
	{
	return EFlashNone;
	}

void CTestCamera::SetExposureL(TExposure aExposure)
	{
	CheckReserveAndPowerL();

	if (aExposure != EExposureAuto)
		{
		User::Leave(KErrNotSupported);
		}
	}

CCamera::TExposure CTestCamera::Exposure() const
	{
	return EExposureAuto;
	}

void CTestCamera::SetWhiteBalanceL(TWhiteBalance aWhiteBalance)
	{
	CheckReserveAndPowerL();

	if (aWhiteBalance != EWBAuto)
		{
		User::Leave(KErrNotSupported);
		}
	}

CCamera::TWhiteBalance CTestCamera::WhiteBalance() const
	{
	return EWBAuto;
	}

void CTestCamera::StartViewFinderDirectL(RWsSession& aWs,CWsScreenDevice& aScreenDevice,RWindowBase& aWindow,TRect& aScreenRect)
	{
	TRect emptyRect;
	StartViewFinderDirectL(aWs,aScreenDevice,aWindow,aScreenRect,emptyRect);
	}

void CTestCamera::StartViewFinderDirectL(RWsSession& aWs,CWsScreenDevice& aScreenDevice,RWindowBase& aWindow,TRect& aScreenRect,TRect& aClipRect)
	{
	if (!iReserved)
		{
		User::Leave(KErrInUse);		
		}
		
	if (!iPowerOn || iViewFinderActive)
		{
		User::Leave(KErrNotReady);	
		}

	iScreenRect = aScreenRect;
	iClipRect = aClipRect;

	delete iDSA;
	iDSA = NULL;
	iViewFinderActive = EFalse;
	iDSA = CDirectScreenAccess::NewL(aWs,aScreenDevice,aWindow,*this);
	iDSA->StartL();
	iViewFinderActive = ETrue;
	iDSA->Gc()->SetOrigin(); // Set Origin to top left of screen (0,0)

	if (!iClipRect.IsEmpty())
		{
		iDSA->Gc()->SetClippingRect(iClipRect);	
		}
	}

void CTestCamera::StartViewFinderBitmapsL(TSize& aSize)
	{
	TRect emptyRect;
	StartViewFinderBitmapsL(aSize,emptyRect);
	}

void CTestCamera::StartViewFinderBitmapsL(TSize& aSize, TRect& aClipRect)
	{
	if (!iReserved)
		{
		User::Leave(KErrInUse);
		}
	if (!iPowerOn || iViewFinderActive)
		{
		User::Leave(KErrNotReady);
		}

	iViewFinderActive = ETrue;
	iScreenRect = TRect(TPoint(0,0), aSize);
	iClipRect = aClipRect;
	iClipRect.Intersection(iScreenRect);

	delete iViewFinderBitmapGc;
	iViewFinderBitmapGc = NULL;
	delete iViewFinderBitmapDev;
	iViewFinderBitmapDev = NULL;
	delete iViewFinderBitmap;
	iViewFinderBitmap = NULL;

	iViewFinderBitmap = new(ELeave) CFbsBitmap;
	if (!iClipRect.IsEmpty())
		{
		User::LeaveIfError(iViewFinderBitmap->Create(iClipRect.Size(), KViewFinderDisplayMode));		
		}
	else
		{
		User::LeaveIfError(iViewFinderBitmap->Create(aSize, KViewFinderDisplayMode));		
		}
	iViewFinderBitmapDev = CFbsBitmapDevice::NewL(iViewFinderBitmap);
	User::LeaveIfError(iViewFinderBitmapDev->CreateContext(iViewFinderBitmapGc));
	}
	
void CTestCamera::StartViewFinderL(TFormat aImageFormat,TSize& aSize)
       {
       TRect emptyRect;
       StartViewFinderL(aImageFormat,aSize,emptyRect);
       }
	
void CTestCamera::StartViewFinderL(TFormat aImageFormat,TSize& /*aSize*/,TRect& aClipRect)	
       {
     	if(!iReserved)
     		{
     		User::Leave(KErrInUse);
     		}
		if(!iPowerOn || iViewFinderActive)
			{
			User::Leave(KErrNotReady);
			}
		
		iViewFinderActive = ETrue;
		iClipRect = aClipRect;
		if(!(aImageFormat & iInfo.iImageFormatsSupported))
			{
			 User::Leave(KErrNotSupported);
			}
       }
       

void CTestCamera::StopViewFinder()
	{
	iViewFinderActive = EFalse;
	delete iDSA;
	iDSA = NULL;

	delete iViewFinderBitmapGc;
	iViewFinderBitmapGc = NULL;
	delete iViewFinderBitmapDev;
	iViewFinderBitmapDev = NULL;
	delete iViewFinderBitmap;
	iViewFinderBitmap = NULL;
	}

TBool CTestCamera::ViewFinderActive() const
	{
	return iViewFinderActive;
	}

void CTestCamera::SetViewFinderMirrorL(TBool aMirror)
	{
	if (aMirror)
		{
		User::Leave(KErrNotSupported);	
		}
	}

TBool CTestCamera::ViewFinderMirror() const
	{
	return EFalse;
	}

void CTestCamera::PrepareImageCaptureL(TFormat aImageFormat,TInt aSizeIndex)
	{
	if (!iReserved)
		{
		User::Leave(KErrInUse);
		}
		
	if (!iPowerOn || iVideoCaptureActive || iImageCaptureActive)
		{
		User::Leave(KErrNotReady);
		}
		

	if (!(aImageFormat & iInfo.iImageFormatsSupported) || aSizeIndex < 0
		|| aSizeIndex >= iInfo.iNumImageSizesSupported)
		{
		User::Leave(KErrNotSupported);
		}

	iVideoPreparedLast = EFalse;

	if (iImageCapturePrepared
		&& iStillImageSize == iImageSizes[aSizeIndex]
		&& iStillImageFormat == aImageFormat)
		{
		return;
		}

	iStillImageSize = iImageSizes[aSizeIndex];
	iStillImageFormat = aImageFormat;

	TDisplayMode displayMode = ENone;
	switch (iStillImageFormat)
		{
		case EFormatFbsBitmapColor4K :
			displayMode = EColor4K;
			break;
		case EFormatFbsBitmapColor64K :
			displayMode = EColor64K;
			break;
		case EFormatFbsBitmapColor16M :
			displayMode = EColor16M;
			break;
		default :
			User::Leave(KErrNotSupported);
			break;
		}

	delete iStillImageGc;
	iStillImageGc = NULL;
	delete iStillImageDev;
	iStillImageDev = NULL;
	delete iStillImage;
	iStillImage = NULL;

	iStillImage = new(ELeave) CFbsBitmap;
	User::LeaveIfError(iStillImage->Create(iStillImageSize, displayMode));
	iStillImageDev = CFbsBitmapDevice::NewL(iStillImage);
	User::LeaveIfError(iStillImageDev->CreateContext(iStillImageGc));
	iStillImageGc->SetPenColor(KRgbBlack);
	iStillImageGc->SetPenSize(TSize(KFrameFeatureBorderThickness, KFrameFeatureBorderThickness));
	iStillImageGc->SetBrushColor(KRgbWhite);
	iStillImageGc->SetFaded(ETrue);
	iImageCapturePrepared = ETrue;
	}

void CTestCamera::PrepareImageCaptureL(TFormat /*aImageFormat*/,TInt /*aSizeIndex*/,const TRect& /*aClipRect*/)
	{
	User::Leave(KErrNotSupported);
	}

void CTestCamera::CaptureImage()
	{
	if (!iReserved)
		{
		iStillCaptureErr = KErrInUse;
		}
		
	if (!iPowerOn || iImageCaptureActive || iVideoCaptureActive || !iImageCapturePrepared)
		{
		iStillCaptureErr = KErrNotReady;
		}

	if (iStillCaptureErr == KErrNone)
		{
		TRAP(iStillCaptureErr,DoCaptureImageL());
		}

	if (iStillCaptureErr == KErrNone)
		{
		iImageCaptureActive = ETrue;
		}
	else
		{
		iImageCaptureAsync.CallBack();
		}
	}

void CTestCamera::DoCaptureImageL()
	{
	delete iGc;
	iGc = NULL;
	delete iDev;
	iDev = NULL;
	delete iImage;
	iImage = NULL;

	CFbsBitmap* image = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(image);
	User::LeaveIfError(image->Create(iStillImageSize, iStillImage->DisplayMode()));
	CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(image);
	CleanupStack::PushL(dev);
	CFbsBitGc* gc = NULL;
	User::LeaveIfError(dev->CreateContext(gc));
	CleanupStack::Pop(dev);
	CleanupStack::Pop(image);

	iImage = image;
	iDev = dev;
	iGc = gc;
	}

void CTestCamera::CancelCaptureImage()
	{
	iImageCaptureActive = EFalse;
	}

void CTestCamera::EnumerateCaptureSizes(TSize& aSize,TInt aSizeIndex,TFormat aFormat) const
	{
	if (aSizeIndex < 0 || aSizeIndex >= iInfo.iNumImageSizesSupported ||
		!(aFormat & iInfo.iImageFormatsSupported) )
		{
		aSize = TSize(0,0);
		}
	else
		{
		aSize = iImageSizes[aSizeIndex];
		}
	}

void CTestCamera::PrepareVideoCaptureL(TFormat aFormat,TInt aSizeIndex,TInt aRateIndex,TInt aBuffersToUse,TInt aFramesPerBuffer)
	{
	if (!iReserved)
		{
		User::Leave(KErrInUse);
		}
		
	if (!iPowerOn || iVideoCaptureActive || iImageCaptureActive)
		{
		User::Leave(KErrNotReady);
		}

	if (!(aFormat & iInfo.iVideoFrameFormatsSupported) 
		|| aSizeIndex < 0 || aSizeIndex >= iInfo.iNumVideoFrameSizesSupported
		|| aRateIndex < 0 || aRateIndex >= iInfo.iNumVideoFrameRatesSupported
		|| aBuffersToUse != 2 || aFramesPerBuffer != 1)
		{
		User::Leave(KErrNotSupported);
		}

	iVideoPreparedLast = ETrue;

	if (iVideoCapturePrepared 
		&& iVideoFrameSize == iVideoFrameSizes[aSizeIndex]
		&& iVideoFrameFormat == aFormat)
		{
		return;
		}

	TDisplayMode displayMode = ENone;
	switch (aFormat)
		{
		case EFormatFbsBitmapColor4K :
			displayMode = EColor4K;
			break;
		case EFormatFbsBitmapColor64K :
			displayMode = EColor64K;
			break;
		case EFormatFbsBitmapColor16M :
			displayMode = EColor16M;
			break;
		default :
			User::Leave(KErrNotSupported);
			break;
		}

	iVideoFrameSize = iVideoFrameSizes[aSizeIndex];
	iVideoFrameRate = iVideoFrameRates[aRateIndex];
	iVideoFrameFormat = aFormat;
	iBuffersInUse = aBuffersToUse;

	delete iVideoFrameGc1;
	iVideoFrameGc1 = NULL;
	delete iVideoFrameDev1;
	iVideoFrameDev1 = NULL;
	delete iVideoFrame1;
	iVideoFrame1 = NULL;

	delete iVideoFrameGc2;
	iVideoFrameGc2 = NULL;
	delete iVideoFrameDev2;
	iVideoFrameDev2 = NULL;
	delete iVideoFrame2;
	iVideoFrame2 = NULL;

	iVideoFrame1 = new(ELeave) CFbsBitmap;
	User::LeaveIfError(iVideoFrame1->Create(iVideoFrameSize, displayMode));
	iVideoFrameDev1 = CFbsBitmapDevice::NewL(iVideoFrame1);
	User::LeaveIfError(iVideoFrameDev1->CreateContext(iVideoFrameGc1));
	iVideoFrameGc1->SetPenColor(KRgbBlack);
	iVideoFrameGc1->SetPenSize(TSize(KFrameFeatureBorderThickness, KFrameFeatureBorderThickness));
	iVideoFrameGc1->SetBrushColor(KRgbWhite);
	iVideoFrameGc1->SetFaded(ETrue);

	if (iBuffersInUse == 2)
		{
		iVideoFrame2 = new(ELeave) CFbsBitmap;
		User::LeaveIfError(iVideoFrame2->Create(iVideoFrameSize, displayMode));
		iVideoFrameDev2 = CFbsBitmapDevice::NewL(iVideoFrame2);
		User::LeaveIfError(iVideoFrameDev1->CreateContext(iVideoFrameGc2));
		iVideoFrameGc2->SetPenColor(KRgbBlack);
		iVideoFrameGc2->SetPenSize(TSize(KFrameFeatureBorderThickness, KFrameFeatureBorderThickness));
		iVideoFrameGc2->SetBrushColor(KRgbWhite);
		iVideoFrameGc2->SetFaded(ETrue);		
		}

	iVideoCapturePrepared = ETrue;
	}

void CTestCamera::PrepareVideoCaptureL(TFormat /*aFormat*/,TInt /*aSizeIndex*/,TInt /*aRateIndex*/,TInt /*aBuffersToUse*/,TInt /*aFramesPerBuffer*/,const TRect& /*aClipRect*/)
	{
	User::Leave(KErrNotSupported);
	}

void CTestCamera::StartVideoCapture()
	{
	if (!iReserved)
		{
		iVideoCaptureErr = KErrInUse;
		}
		
	if (!iPowerOn || iImageCaptureActive || iVideoCaptureActive || !iVideoCapturePrepared)
		{
		iVideoCaptureErr = KErrNotReady;
		}
		
	if (iVideoCaptureErr == KErrNone)
		{
		iVideoCaptureActive = ETrue;
		}
		
	else
		{
		iVideoCaptureAsync.CallBack();
		}
	}

void CTestCamera::StopVideoCapture()
	{
	iVideoCaptureActive = EFalse;
	iFrameIndex = 0;
	iElapsedTime = 0;
	}

TBool CTestCamera::VideoCaptureActive() const
	{
	return iVideoCaptureActive;
	}

void CTestCamera::EnumerateVideoFrameSizes(TSize& aSize,TInt aSizeIndex,TFormat aFormat) const
	{
	if (aSizeIndex < 0 || aSizeIndex >= iInfo.iNumVideoFrameSizesSupported ||
		!(aFormat & iInfo.iVideoFrameFormatsSupported))
		{
		aSize = TSize(0,0);
		}
	else
		{
		aSize = iVideoFrameSizes[aSizeIndex];
		}
	}

void CTestCamera::EnumerateVideoFrameRates(TReal32& aRate,TInt aRateIndex,TFormat aFormat,TInt aSizeIndex,TExposure aExposure) const
	{
	if (aRateIndex < 0 || aRateIndex >= iInfo.iNumVideoFrameRatesSupported ||
		aSizeIndex < 0 || aSizeIndex >= iInfo.iNumVideoFrameSizesSupported ||
		!(aFormat & iInfo.iVideoFrameFormatsSupported) ||
		(!(aExposure & iInfo.iExposureModesSupported) && aExposure != CCamera::EExposureAuto))
		{
		aRate = 0.0;
		}
	else
		{
		aRate = iVideoFrameRates[aRateIndex];
		}
	}

void CTestCamera::GetFrameSize(TSize& aSize) const
	{
	aSize = iVideoFrameSize;
	}

TReal32 CTestCamera::FrameRate() const
	{
	return iVideoFrameRate;
	}

TInt CTestCamera::BuffersInUse() const
	{
	return iBuffersInUse;
	}

TInt CTestCamera::FramesPerBuffer() const
	{
	return 1;
	}

void CTestCamera::SetJpegQuality(TInt /*aQuality*/)
	{
	}

TInt CTestCamera::JpegQuality() const
	{
	return 0;
	}

TAny* CTestCamera::CustomInterface(TUid aInterface)
	{
	TAny* ptrIface = NULL;
	TRAPD(error,CustomInterfaceL(ptrIface, aInterface));
	
	if(error == KErrNone)
		{
		switch(aInterface.iUid)
			{
			// advanced settings interface pointers
			case KECamMCameraAdvancedSettingsUidValue:
				{
				return static_cast<MCameraAdvancedSettings*>(ptrIface);
				}
			case KECamMCameraAdvancedSettings2UidValue:
				{
				return static_cast<MCameraAdvancedSettings2*>(ptrIface);			
				}
			case KECamMCameraAdvancedSettings3UidValue:
				{
				return static_cast<MCameraAdvancedSettings3*>(ptrIface);
				}
			
			// snapshot interface pointers	
			case KECamMCameraSnapshotUidValue:
				{
				return static_cast<MCameraSnapshot*>(ptrIface);
				}
				
			// preset interface pointers	
			case KECamMCameraPresetsUidValue:
				return static_cast<MCameraPresets*>(ptrIface);
				
			// image processing interface pointers
			case KECamMCameraImageProcessingUidValue:
				{
				return static_cast<MCameraImageProcessing*>(ptrIface);
				}
				
			case KECamMCameraImageProcessing2UidValue:
				{
				return static_cast<MCameraImageProcessing2*>(ptrIface);
				}
				
			default:
				return NULL;
			}
		}
	else
		{
		return NULL;		
		}
	}

void CTestCamera::CustomInterfaceL(TAny*& aIface, TUid aInterface)
	{
	switch(aInterface.iUid)
		{
		// advanced settings interface pointers
		case KECamMCameraAdvancedSettingsUidValue:
			{
			iAdvSettingsImpl = CTestCamAdvSet::NewL(*this);
			aIface = static_cast<MCameraAdvancedSettings*>(iAdvSettingsImpl);
			break;
			}
		case KECamMCameraAdvancedSettings2UidValue:
			{
			iAdvSettingsImpl = CTestCamAdvSet::NewL(*this);
			aIface = static_cast<MCameraAdvancedSettings2*>(iAdvSettingsImpl);			
			break;
			}
		case KECamMCameraAdvancedSettings3UidValue:
			{
			iAdvSettingsImpl = CTestCamAdvSet::NewL(*this);
			aIface = static_cast<MCameraAdvancedSettings3*>(iAdvSettingsImpl);
			break;
			}
		
		// snapshot interface pointers	
		case KECamMCameraSnapshotUidValue:
			{
			iSnapshotImpl = CTestCamSnapshot::NewL(*this);
			aIface = static_cast<MCameraSnapshot*>(iSnapshotImpl);
			break;
			}
		// preset interface pointers	
		case KECamMCameraPresetsUidValue:
			{
			aIface = static_cast<MCameraPresets*>(CTestCamPresets::NewL(*this));
			break;
			}
			
		// image processing interface pointers
		case KECamMCameraImageProcessingUidValue:
			{
			iImgProcImpl = CTestCamImgProc::NewL(*this);	
			aIface = static_cast<MCameraImageProcessing*>(iImgProcImpl);
			break;
			}
			
		case KECamMCameraImageProcessing2UidValue:
			{
			iImgProcImpl = CTestCamImgProc::NewL(*this);	
			aIface = static_cast<MCameraImageProcessing2*>(iImgProcImpl);
			break;
			}
			
		default:
			aIface = NULL;
		}
	}

void CTestCamera::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
	{
	iViewFinderActive = EFalse;
	}

void CTestCamera::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
	{
	TRAPD(error,iDSA->StartL());
	if (error != KErrNone)
		{
		return;
		}
	iDSA->Gc()->SetOrigin(); // Set Origin to top left of screen (0,0)

	if (!iClipRect.IsEmpty())
		{
		iDSA->Gc()->SetClippingRect(iClipRect);
		}
	else
		{
		iDSA->Gc()->CancelClippingRect();
		}

	iViewFinderActive = ETrue;
	}

TInt CTestCamera::TimerCallBack(TAny* aThis)
	{
	static_cast<CTestCamera*>(aThis)->FrameReady();
	return KErrNone;
	}

void CTestCamera::FrameReady()
	{
	if (iVideoPreparedLast)
		{
		iVideoFramePos.iX += KFramePosIncrement;
		iVideoFramePos.iY += KFramePosIncrement;

		if (iVideoFramePos.iX >= iVideoFrameSize.iWidth)
			{
			iVideoFramePos.iX = 0;
			}
			
		if (iVideoFramePos.iY >= iVideoFrameSize.iHeight)
			{
			iVideoFramePos.iY = 0;
			}
		}
	else
		{
		iStillImagePos.iX += KFramePosIncrement;
		iStillImagePos.iY += KFramePosIncrement;

		if (iStillImagePos.iX >= iStillImageSize.iWidth)
			{
			iStillImagePos.iX = 0;
			}
			
		if (iStillImagePos.iY >= iStillImageSize.iHeight)
			{
			iStillImagePos.iY = 0;
			}
		}

	if (iImageCaptureActive)
		{
		if (!iImageCapturePrepared)
			{
			iImageCaptureActive = EFalse;
			if (iObserver2)
				{
				iObserver2->ImageBufferReady(iFrameCameraBuffer1,KErrNotReady);
				}
			else
				{
				iObserver->ImageReady(NULL,NULL,KErrNotReady);
				}
			}
		else
			{
			if(iDriveMode == CCamera::CCameraAdvancedSettings::EDriveModeBurst)
				{
				for (TInt index =0; index < iBurstImages -1; index++)
					{
					if(iSnapshotImpl != NULL)
						{
						if(iSnapshotImpl->iSnapshotActive)
							{
							GetFrame(*(iSnapshotImpl->iSnapshotImageGc), iStillImagePos);
							iSnapshotImpl->ServiceBurstImageSnapshot(*(iSnapshotImpl->iSnapshotImageGc));
							}
						}
					
					GetImgProcessedFrame(*iStillImageGc, iStillImagePos);
					ServiceBurstImageCapture(*iStillImageGc);
					}
				}
				
			// normal case, single shot and last image from burst mode
			if(iSnapshotImpl != NULL)
				{
				if(iSnapshotImpl->iSnapshotActive)
					{
					GetFrame(*iSnapshotImpl->iSnapshotImageGc, iStillImagePos);
					iSnapshotImpl->ServiceSnapshot(*(iSnapshotImpl->iSnapshotImageGc));
					}
				}
				
			GetImgProcessedFrame(*iStillImageGc, iStillImagePos);
			ServiceImageCapture(*iStillImageGc);	
							
			if (iVideoPreparedLast)
				{
				GetFrame(*iVideoFrameGc1, iVideoFramePos);
				if (iViewFinderActive)
					{
					ServiceViewFinder(iVideoFrame1);
					}	
				}
			else
				{
				if (iViewFinderActive)
					{
					ServiceViewFinder(iStillImage);
					}
				}
			}
		}

	else if (iVideoCaptureActive)
		{
		if (!iVideoCapturePrepared)
			{
			iVideoCaptureActive = EFalse;
			if (iObserver2)
				{
				iObserver2->VideoBufferReady(iFrameCameraBuffer1,KErrNotReady);
				}
			else
				{
				iObserver->FrameBufferReady(NULL,KErrNotReady);
				}
			}
		else
			{
			if (iObserver2)
				{
				if (iFrameCameraBuffer1.iAvailable)
					{
					GetFrame(*iVideoFrameGc1, iVideoFramePos);
					ServiceVideo(1);
					if (iViewFinderActive)
						{
						ServiceViewFinder(iVideoFrame1);
						}
					}
				else if (iFrameCameraBuffer2.iAvailable && iBuffersInUse == 2)
					{
					GetFrame(*iVideoFrameGc2, iVideoFramePos);
					ServiceVideo(2);
					if (iViewFinderActive)
						{
						ServiceViewFinder(iVideoFrame2);
						}
					}
				}
			else
				{
				if (iFrameBuffer1.iAvailable)
					{
					GetFrame(*iVideoFrameGc1, iVideoFramePos);
					ServiceVideo(1);
					if (iViewFinderActive)
						{
						ServiceViewFinder(iVideoFrame1);
						}
					}
				else if (iFrameBuffer2.iAvailable && iBuffersInUse == 2)
					{
					GetFrame(*iVideoFrameGc2, iVideoFramePos);
					ServiceVideo(2);
					if (iViewFinderActive)
						{
						ServiceViewFinder(iVideoFrame2);
						}
					}
				}
			}
	}

	else if (iViewFinderActive)
		{
		if (iVideoPreparedLast)
			{
			GetFrame(*iVideoFrameGc1, iVideoFramePos);
			ServiceViewFinder(iVideoFrame1);
			}
			else
			{
			GetFrame(*iStillImageGc, iStillImagePos);
			ServiceViewFinder(iStillImage);
			}
		}
	}

void CTestCamera::GetFrame(CFbsBitGc& aGc, TPoint& aPos) const
	{
	TInt black = (100 - iContrast) * 127 / 200;
	TInt white = ((100 + iContrast) * 128 / 200) + 127;

	const TInt brightAdjust = iBrightness * 255 / 100;
	black += brightAdjust;
	white += brightAdjust;

	black = Min(Max(black,0),255);
	white = Min(Max(white,0),255);

	aGc.SetFadingParameters(TUint8(black),TUint8(white));
	aGc.Clear();
	aGc.DrawRect(TRect(aPos,TSize(KFrameFeatureSize,KFrameFeatureSize)));
	}
	
void CTestCamera::GetImgProcessedFrame(CFbsBitGc& aGc, TPoint& aPos) const
	{
	TInt contrast = iContrast;
	TInt brightness = iBrightness;
	
	if(iImgProcImpl != NULL)
		{
		for(TInt index=0; index<iImgProcImpl->iActiveTransformations.Count(); index++)
			{
			switch(iImgProcImpl->iActiveTransformations[index].iUid)
				{
				case KUidECamEventImageProcessingAdjustBrightnessUidValue:
					{
					brightness = iImgProcBrightness;
					break;
					}
				case KUidECamEventImageProcessingAdjustContrastUidValue:
					{
					contrast = iImgProcContrast;
					break;
					}
				default:
					{
					break;
					}
				}
			}
		}
	
	TInt black = (100 - contrast) * 127 / 200;
	TInt white = ((100 + contrast) * 128 / 200) + 127;

	const TInt brightAdjust = brightness * 255 / 100;
	black += brightAdjust;
	white += brightAdjust;

	black = Min(Max(black,0),255);
	white = Min(Max(white,0),255);

	aGc.SetFadingParameters(TUint8(black),TUint8(white));
	aGc.Clear();
	aGc.DrawRect(TRect(aPos,TSize(KFrameFeatureSize,KFrameFeatureSize)));
	}
	
void CTestCamera::ServiceVideo(TInt aBufferNum)
	{
	iFrameIndex++;
	iElapsedTime = iElapsedTime.Int64() + (TInt64(1000000) / TInt64(iVideoFrameRate));

	if (aBufferNum == 1)
		{
		if (iObserver2)
			{
			iFrameCameraBuffer1.iIndexOfFirstFrameInBuffer = iFrameIndex;
			iFrameCameraBuffer1.iElapsedTime = iElapsedTime;
			iFrameCameraBuffer1.iAvailable = EFalse;
			}
		else
			{
			iFrameBuffer1.iIndexOfFirstFrameInBuffer = iFrameIndex;
			iFrameBuffer1.iElapsedTime = iElapsedTime;
			iFrameBuffer1.iAvailable = EFalse;
			}
			
		if (iObserver2)
			{
			iObserver2->VideoBufferReady(iFrameCameraBuffer1,KErrNone);
			}
		else
			{
			iObserver->FrameBufferReady(&iFrameBuffer1,KErrNone);
			}
		}
	else if (aBufferNum == 2)
		{
		if (iObserver2)
			{
			iFrameCameraBuffer2.iIndexOfFirstFrameInBuffer = iFrameIndex;
			iFrameCameraBuffer2.iElapsedTime = iElapsedTime;
			iFrameCameraBuffer2.iAvailable = EFalse;
			}
		else
			{
			iFrameBuffer2.iIndexOfFirstFrameInBuffer = iFrameIndex;
			iFrameBuffer2.iElapsedTime = iElapsedTime;
			iFrameBuffer2.iAvailable = EFalse;
			}
			
		if (iObserver2)
			{
			iObserver2->VideoBufferReady(iFrameCameraBuffer2,KErrNone);
			}
		else
			{
			iObserver->FrameBufferReady(&iFrameBuffer2,KErrNone);
			}
		}
	}

void CTestCamera::ServiceViewFinder(CFbsBitmap* aSourceFrame)
	{
	if (iDSA)
		{
		iDSA->Gc()->DrawBitmap(iScreenRect,aSourceFrame);
		iDSA->ScreenDevice()->Update();
		}
	else if (iViewFinderBitmap)
		{
		if (iViewFinderBitmapGc)
			{
			if (!iClipRect.IsEmpty())
				{
				TReal32 xRatio = static_cast<TReal32>(aSourceFrame->SizeInPixels().iWidth) / 
								 static_cast<TReal32>(iClipRect.Size().iWidth);

				TReal32 yRatio = static_cast<TReal32>(aSourceFrame->SizeInPixels().iHeight) / 
								 static_cast<TReal32>(iClipRect.Size().iHeight);

				TRect sourceRect(TPoint(static_cast<TInt>(xRatio*iClipRect.iTl.iX),
										static_cast<TInt>(yRatio*iClipRect.iTl.iY)),
								 TPoint(static_cast<TInt>(xRatio*iClipRect.iBr.iX),
										static_cast<TInt>(yRatio*iClipRect.iBr.iY)));

				TRect destRect(TPoint(0,0), iClipRect.Size());

				iViewFinderBitmapGc->DrawBitmap(destRect,
												aSourceFrame,
												sourceRect);
				}
			else
				{
				TRect destRect(TPoint(0,0), iViewFinderBitmap->SizeInPixels());
				iViewFinderBitmapGc->DrawBitmap(destRect, aSourceFrame);
				}
				
			if (iObserver2)
				{
				iObserver2->ViewFinderReady(iFrameCameraBuffer1,KErrNone);
				}
			else
				{
				iObserver->ViewFinderFrameReady(*iViewFinderBitmap);
				}
		
			}
		}
	else
		{
		iScreenGc->DrawBitmap(iClipRect,aSourceFrame);
		iScreenDev->Update();
		}
	}

void CTestCamera::ServiceImageCapture(const CFbsBitGc& aSourceBitmapGc)
	{
	iImageCaptureActive = EFalse;
	iGc->BitBlt(TPoint(0,0), aSourceBitmapGc);
	CFbsBitmap* image = iImage;
	RTestCameraFrameBuffer frameBuffer(image);
	delete iGc;
	iGc = NULL;
	delete iDev;
	iDev = NULL;
	if (iObserver2 != NULL)
		{
		iObserver2->ImageBufferReady(frameBuffer,KErrNone);
		}
	else
		{
		iImage = NULL;
		iObserver->ImageReady(image,NULL,KErrNone);
		}
	}
	
void CTestCamera::ServiceBurstImageCapture(const CFbsBitGc& aSourceBitmapGc)
	{
	iGc->BitBlt(TPoint(0,0), aSourceBitmapGc);
	if (iObserver2 != NULL)
		{
		CFbsBitmap* image = iImage;
		RTestCameraFrameBuffer frameBuffer(image);
		iObserver2->ImageBufferReady(frameBuffer,KErrNone);
		}
	else//not for MCameraObserver
		{
		return;
		}
	
	if(iSnapshotImpl)
		{
		if(iSnapshotImpl->iSnapshotActive)
			{
			return;
			}
		}
	User::After(500000);
	iStillImagePos.iX += KFramePosIncrement;
	iStillImagePos.iY += KFramePosIncrement;

	if (iStillImagePos.iX >= iStillImageSize.iWidth)
		{
		iStillImagePos.iX = 0;
		}
			
	if (iStillImagePos.iY >= iStillImageSize.iHeight)
		{
		iStillImagePos.iY = 0;
		}
	}

void CTestCamera::CheckReserveAndPowerL()
	{
	if (!iReserved)
		{
		User::Leave(KErrInUse);
		}
		
	if (!iPowerOn)
		{
		User::Leave(KErrNotReady);
		}	
	}

TInt CTestCamera::CheckReserveAndPower() const
	{
	if (!iReserved)
		{
		return KErrInUse;
		}
		
	if (!iPowerOn)
		{
		return KErrNotReady;
		}	
	
	return KErrNone;
	}

TInt CTestCamera::ReserveCallBack(TAny* aThis)
	{
	const TECAMEvent event(KUidECamEventReserveComplete,KErrNone);
	CTestCamera* testCamera = static_cast<CTestCamera*>(aThis);
	if (testCamera->iObserver2)
		{
		testCamera->iObserver2->HandleEvent(event);
		}
	else
		{
		testCamera->iObserver->ReserveComplete(KErrNone);
		}
	return KErrNone;
	}

TInt CTestCamera::PowerOnCallBack(TAny* aThis)
	{
	TECAMEvent event(KUidECamEventPowerOnComplete,KErrNone);
	CTestCamera* testCamera = static_cast<CTestCamera*>(aThis);
	if (testCamera->iObserver2)
		{
		testCamera->iObserver2->HandleEvent(event);
		}
	else
		{
		testCamera->iObserver->PowerOnComplete(testCamera->iPowerOn ? KErrNone : KErrInUse);
		}
	return KErrNone;
	}

TInt CTestCamera::ImageCaptureCallBack(TAny* aThis)
	{
	CTestCamera* testCamera = static_cast<CTestCamera*>(aThis);
	if (testCamera->iObserver2)
		{
		testCamera->iObserver2->ImageBufferReady((static_cast<CTestCamera*>(aThis))->iFrameCameraBuffer1,testCamera->iStillCaptureErr);
		}
	else
		{
		testCamera->iObserver->ImageReady(NULL,NULL,testCamera->iStillCaptureErr);
		}
	testCamera->iStillCaptureErr = KErrNone;
	return KErrNone;
	}

TInt CTestCamera::VideoCaptureCallBack(TAny* aThis)
	{
	CTestCamera* testCamera = static_cast<CTestCamera*>(aThis);
	if (testCamera->iObserver2)
		{
		testCamera->iObserver2->VideoBufferReady((static_cast<CTestCamera*>(aThis))->iFrameCameraBuffer1,testCamera->iVideoCaptureErr);
		}
	else
		{
		testCamera->iObserver->FrameBufferReady(NULL,testCamera->iVideoCaptureErr);
		}
	testCamera->iVideoCaptureErr = KErrNone;
	return KErrNone;
	}
	
TInt CTestCamera::HandleEventCallBack(TAny* aThis)
	{
	CTestCamera* testCamera = static_cast<CTestCamera*>(aThis);
	if (testCamera->iObserver2)
		{
		testCamera->iObserver2->HandleEvent(testCamera->iECamEvent);
		}
	
	return KErrNone;
	}

TInt CTestCamera::HandleEvent2CallBack(TAny* aThis)
	{
	CTestCamera* testCamera = static_cast<CTestCamera*>(aThis);
	if (testCamera->iObserver2)
		{
		testCamera->iObserver2->HandleEvent(testCamera->iECamEvent2);
		}
	
	return KErrNone;
	}

//
// CTestCameraInfo
//

CTestCameraInfo::CTestCameraInfo()
	{
	}
	
CTestCameraInfo::~CTestCameraInfo()
	{
	}
	
CTestCameraInfo* CTestCameraInfo::NewL()
	{
	FileDependencyUtil::CheckFileDependencyL();
	return new (ELeave) CTestCameraInfo;
	}
	
TInt CTestCameraInfo::CamerasAvailable()
	{
	return 1;
	}

//void CTestCamera::CheckFileDependencyL()
void FileDependencyUtil::CheckFileDependencyL()
	{	
	RFs fsSession;
  	RFile file;
    CleanupClosePushL(fsSession);
  	User::LeaveIfError(fsSession.Connect());
    TInt err = file.Open(fsSession, KTestCameraPluginName, EFileRead);
  	file.Close();
  	if(err != KErrNone)
  		{
	    User::LeaveIfError(KErrNotSupported);
  		}
  	CleanupStack::PopAndDestroy(); //fsSession 
	}

// __________________________________________________________________________
// Exported proxy for instantiation method resolution
// Define the interface UIDs
const TImplementationProxy ImplementationTable[] = 
	{
	IMPLEMENTATION_PROXY_ENTRY(KUidOnboardCameraTestPlugin,	CTestCamera::NewL),
	IMPLEMENTATION_PROXY_ENTRY(KUidOnboardCameraTestInfo,	CTestCameraInfo::NewL)
	};

EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
	{
	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);

	return ImplementationTable;
	}