camerauis/cameraapp/generic/src/CamDocument.cpp
branchRCL_3
changeset 24 bac7acad7cb3
parent 0 1ddebce53859
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/camerauis/cameraapp/generic/src/CamDocument.cpp	Wed Sep 01 12:30:54 2010 +0100
@@ -0,0 +1,1095 @@
+/*
+* Copyright (c) 2007 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:  Document class for Camera Application*
+*/
+
+#include "camlogging.h"
+#include "CamLogger.h"
+
+#ifdef _DEBUG
+#include <e32debug.h>
+
+
+//#define _AO_TRACKING
+#ifdef _AO_TRACKING
+
+static void ReplaceCurrentASL();
+static void RestoreCurrentAS();
+
+class CFilterScheduler;
+
+class CFilterInfo : public CBase
+    {
+    friend class CFilterScheduler;
+
+public:
+    static CFilterInfo* NewL();
+
+protected:
+    struct CFilterStruct
+        {
+        CFilterStruct(CActive* aActiveAddPointer, char* aActiveLogInfo,
+                CFilterStruct* aLink);
+        CActive *iActiveAddPointer;
+        char *iActiveLogInfo;
+        CFilterStruct *iLink;
+        };
+
+protected:
+    CFilterInfo();
+    void ConstructL();
+    void AddInfoL(CActive* aActiveAddPointer, char* aActiveLogInfo,
+            CFilterStruct * &aLink);
+    char* FindInfo(CActive *);
+    ~CFilterInfo();
+protected:
+    struct CFilterStruct *iFiSHead;
+
+    };
+
+class CFilterScheduler : public CActiveScheduler
+    {
+    friend void ReplaceCurrentASL();
+    friend void RestoreCurrentAS();
+
+public:
+    static CFilterScheduler* NewL();
+private:
+    static CActiveScheduler* iSavedFS;
+public:
+    using CActiveScheduler::Start;
+    // It is used as a hook, which makes possible to collect meaningful
+    // information about every active object
+    virtual TInt Extension_(TUint aUid, TAny*& a0, TAny* a1);
+protected:
+    void ConstructL();
+    CFilterScheduler();
+    ~CFilterScheduler();
+
+    void DebugPrint();
+    char* FindInfo(CActive *);
+    // it has to default to CActiveScheduler implementations  
+    virtual void WaitForAnyRequest();
+    // it has to default to CActiveScheduler implementations
+    virtual void Error(TInt aError) const;
+    // It has to be implemented since this is a concrete class
+    virtual void OnStarting()
+        {
+        }
+    virtual void OnStopping()
+        {
+        }
+    virtual void Reserved_1()
+        {
+        }
+    virtual void Reserved_2()
+        {
+        }
+private:
+    CFilterInfo *iFilterInfo;
+    };
+
+CActiveScheduler* CFilterScheduler::iSavedFS= NULL;
+
+CFilterInfo* CFilterInfo::NewL()
+    {
+    CFilterInfo* self = new( ELeave ) CFilterInfo();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CFilterInfo::AddInfoL(CActive* aActiveAddPointer, char* aActiveLogInfo,
+        CFilterInfo::CFilterStruct* &aLink)
+    {
+    PRINT( _L("Camera => CFilterInfo::AddInfoL") );
+    CFilterStruct *pFiS = new( ELeave ) CFilterStruct( aActiveAddPointer,
+            aActiveLogInfo, aLink );
+    pFiS->iLink = aLink;
+    aLink = pFiS;
+    }
+
+char* CFilterInfo::FindInfo(CActive *aActive)
+    {
+    char *pInfo = (char *)NULL;
+    CFilterStruct *pFiS = iFiSHead;
+    while (pFiS != NULL)
+        {
+        if (pFiS->iActiveAddPointer == aActive)
+            {
+            pInfo = pFiS->iActiveLogInfo;
+            break;
+            }
+        pFiS = pFiS->iLink;
+        }
+    return pInfo;
+    }
+
+CFilterInfo::CFilterStruct::CFilterStruct(CActive* aActiveAddPointer,
+        char* aActiveLogInfo, CFilterInfo::CFilterStruct* aLink)
+    {
+    iActiveAddPointer = aActiveAddPointer;
+    iActiveLogInfo = aActiveLogInfo;
+    iLink = aLink;
+    }
+
+void CFilterInfo::ConstructL()
+    {
+    }
+
+CFilterInfo::CFilterInfo()
+    {
+    iFiSHead = NULL;
+    }
+
+CFilterInfo::~CFilterInfo()
+    {
+    }
+
+CFilterScheduler* CFilterScheduler::NewL()
+    {
+    CFilterScheduler* self = new( ELeave ) CFilterScheduler();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void ReplaceCurrentASL()
+    {
+    CFilterScheduler *fSH = CFilterScheduler::NewL();
+    //if (fSH != NULL)
+    CFilterScheduler::iSavedFS = CActiveScheduler::Replace(fSH);
+    }
+
+void RestoreCurrentAS()
+    {
+
+    if (CFilterScheduler::iSavedFS != NULL)
+        {
+        CActiveScheduler *iFS =
+                CActiveScheduler::Replace(CFilterScheduler::iSavedFS);
+        delete iFS;
+        }
+
+    }
+
+TInt CFilterScheduler::Extension_(TUint aUid, TAny*& a0, TAny* a1)
+    {
+    if (aUid == 0)
+        {
+        TRAPD( rr, iFilterInfo->AddInfoL( (CActive *)a0, (char *)a1,
+                        iFilterInfo->iFiSHead ) );
+        return rr;
+        }
+    return KErrExtensionNotSupported;;
+    }
+
+void CFilterScheduler::WaitForAnyRequest()
+    {
+    // Here is the printout at every wait
+    DebugPrint();
+    if (iSavedFS)
+        iSavedFS->WaitForAnyRequest();
+    else
+        User::WaitForAnyRequest();
+    }
+
+void CFilterScheduler::Error(TInt aError) const
+    {
+    if (iSavedFS)
+        iSavedFS->Error(aError);
+    }
+
+CFilterScheduler::CFilterScheduler()
+    {
+    }
+
+CFilterScheduler::~CFilterScheduler()
+    {
+    iSavedFS = NULL;
+    }
+
+void CFilterScheduler::ConstructL()
+    {
+    /* iActive = CFilterActive::NewL( this ); */
+    iFilterInfo = CFilterInfo::NewL();
+    }
+
+char* CFilterScheduler::FindInfo(CActive * aA)
+    {
+    char *pFI= NULL;
+    if (iFilterInfo)
+        pFI = iFilterInfo->FindInfo(aA);
+    return pFI;
+    }
+
+void CFilterScheduler::DebugPrint()
+    {
+    RDebug::Print( _L( " Camera => CFilterScheduler::DebugPrint" ));
+    TDblQueIter<CActive> q(iActiveQ);
+    q.SetToFirst();
+    while (q != NULL)
+        {
+        CActive *pR = q++;
+        /* TInt pri = pR->iLink.iPriority; */
+        TInt pri = pR->Priority();
+        TInt stat = pR->iStatus.Int(); // TRequestStatus
+        // find active objects identification string otherwise
+        // print it's address
+        char *pText = FindInfo(pR);
+
+        if (pR->IsActive() )
+            {
+            if (stat == KRequestPending)
+                {
+                // active, pending
+                if (pText)
+                    RDebug::Printf(
+                            "Camera: CFilterScheduler::DebugPrint: %s - active/pending - priority: %d - req status: %d",
+                            pText, pri, stat);
+                else
+                    RDebug::Printf(
+                            "Camera: CFilterScheduler::DebugPrint: %x - active/pending - priority: %d - req status: %d",
+                            (TInt)pR, pri, stat);
+                }
+            else
+                {
+                // active, not pending
+                if (pText)
+                    RDebug::Printf(
+                            "Camera: CFilterScheduler::DebugPrint: %s - active/not pending - priority: %d - req status: %d",
+                            pText, pri, stat);
+                else
+                    RDebug::Printf(
+                            "Camera: CFilterScheduler::DebugPrint: %x - active/not pending - priority: %d - req status: %d",
+                            (TInt)pR, pri, stat);
+                }
+            }
+        else
+            {
+            // not active
+            if (pText)
+                RDebug::Printf(
+                        "Camera: CFilterScheduler::DebugPrint: %s - not active: priority: %d - req status: %x",
+                        pText, pri, stat);
+            else
+                RDebug::Printf(
+                        "Camera: CFilterScheduler::DebugPrint: %x - not active: priority: %d - req status: %x",
+                        (TInt)pR, pri, stat);
+            }
+        }
+    RDebug::Print( _L( "Camera <= CFilterScheduler::DebugPrint" ));
+    }
+#endif // _AO_TRACKING
+#endif // _DEBUG
+// INCLUDE FILES
+#include "CamAppUi.h"
+#include "CamDocument.h"
+#include "CamPerformance.h"
+#include "CamAppController.h"
+
+#ifdef _DEBUG
+// These are used for memory allocation tracing.
+#undef _MEMORY_TRACKING
+//#define _MEMORY_TRACKING
+#ifdef _MEMORY_TRACKING
+#include <e32panic.h>
+
+
+// stores the last RDebug::Print or RDebug::Printf calls
+// string from cameraapp code if SInUse was ETrue
+static char *sLastHeapContext = NULL;
+// controls the context taking if it is EFalse sLastHeapContext is not updated
+// used also by RTraceAllocator::Alloc, Free, Realloc etc.
+static TBool sInUse = EFalse;
+
+// forward declaration for friend statements.
+class PtrAssocArray;
+class RTraceAllocator;
+
+
+// class which stores heap context info
+// per allocation
+// every allocation will have one entry in the hash table
+class AllocHeapContext
+    {
+    // added as friend for writing less set/get methods
+    friend class PtrAssocArray;
+public:
+    AllocHeapContext(TAny* aPtr, TInt aSize, char* aText1,
+            AllocHeapContext *aNext = NULL);
+    ~AllocHeapContext();
+protected:
+    // stored pointer of the allocation  
+    TAny* iPtr;
+    // stored size of the allocation
+    TInt iSize;
+    // context string of the allocation, collected from
+    // RDebug::Print, RDebug::Printf calls
+    char* iText1;
+    // link field to the next context if they are more with same hash value
+    // in PtrAssocArray then they can be linked into a single linked list
+    AllocHeapContext *iNext;
+    };
+
+// class which stores the hash table
+class PtrAssocArray
+    {
+public:
+    // constructor takes a Heap to use for allocations and deallocations done by
+    // this class,
+    // Note: For not perturbing normal allocation/deallocation a separate heap is
+    // used for internal needs. 
+    PtrAssocArray(RHeap *aHeap);
+    ~PtrAssocArray();
+    // insert an element into the list
+    // return KErrArgument if aAHC == NULL
+    // otherwise KErrNone
+    TInt Insert(AllocHeapContext* aAHC);
+    // find an element in the list
+    // return NULL pointer if cannot find, this means
+    // also the case if aPtr == NULL  
+    AllocHeapContext *Find(TAny *aPtr);
+    // removes an element from the list
+    // if aPtr == NULL does nothing and returns KErrArgument.
+    // Returns KErrNotFound and does nothnig if cannot find it.
+    // In normal case return KErrNone.
+    TInt Remove(TAny *aPtr);
+    // Prints the elements in the list
+    void PrintLeaks();
+    // cleans the list. It could be used if implemented for restarting
+    // leak search from a certain point onward.
+    // Note: only the list elements are cleaned, for real deallocation purposes
+    // it cannot be used as this system doesn't offers a reference counting of
+    // the pointer. It still can be used even that idea for debugging.  
+    void CleanTables();
+protected:
+    // the hash function itself,
+    // simply takes the middle 2 bytes of a 4 byte unsigned,
+    // to which the pointer is converted  
+    TUint Hash(TAny *aPtr);
+    // internal structures for has array entries
+    // iInfo points
+    struct AssocHashTbl
+        {
+        AllocHeapContext* iInfo;
+        };
+    // the hash array
+    AssocHashTbl iAHT[65536];
+    // pointer to iOwnHeap of
+    RHeap *iHeap;
+    };
+
+// the allocator class
+class RTraceAllocator : public RAllocator
+    {
+public:
+    // return current heap, just utility  
+    static RTraceAllocator* OwnAllocator()
+        {
+        RTraceAllocator& currentHeap = (RTraceAllocator &)User::Heap();
+        return &currentHeap;
+        }
+    // Simple utility function for getting a size of a char*
+    // User::StringLength looks similar,
+    // but this return 0 if aStr == NULL.
+    static TUint StrSize(char * aStr);
+    // stores the current heap for calls forwarding to that ones
+    // implementation
+    RTraceAllocator(RHeap *aCurrentHeap);
+    // destructor sets sInUse to EFalse as iOwnHeap is not available any
+    // more
+    ~RTraceAllocator()
+        {
+        iOwnHeap->Close();
+        sInUse = EFalse;
+        }
+
+    // These virtuals needs to be overwritten
+    // there functionality is documented by Symbian
+    virtual TAny* Alloc(TInt aSize);
+    virtual void Free(TAny* aPtr);
+    virtual TAny* ReAlloc(TAny* aPtr, TInt aSize, TInt aMode = 0);
+    virtual TInt AllocLen(const TAny* aCell) const;
+    virtual TInt Compress();
+    virtual void Reset();
+    virtual TInt AllocSize(TInt& aTotalAllocSize) const;
+    virtual TInt Available(TInt& aBiggestBlock) const;
+    virtual TInt DebugFunction(TInt aFunc, TAny* a1=NULL, TAny* a2=NULL);
+    // print entries in hash table, it is just a proxy method 
+    void PrintLeaks()
+        {
+        iAHM->PrintLeaks();
+        }
+    // clean the tables it is just a proxy
+    void CleanTables()
+        {
+        iAHM->CleanTables();
+        }
+    // frees memory from own heap
+    void FreeOwn(TAny* aPtr)
+        {
+        iOwnHeap->Free(aPtr);
+        }
+    // allocates from own heap and fills with 0
+    TAny* AllocZOwn(TInt aSize)
+        {
+        return iOwnHeap->AllocZ(aSize);
+        }
+    // returns the saved heap
+    RHeap* SavedHeap()
+        {
+        return iHeap;
+        }
+
+protected:
+    // the original heap of the application, which does the real
+    // allocation. All allocations are deferred to it  
+    RHeap* iHeap;
+    // A heap for own allocations, different than the one used by
+    // cameraapp process 
+    RHeap* iOwnHeap;
+    // pointer to the hash table
+    PtrAssocArray* iAHM;
+    };
+
+
+#if defined( _UNICODE )
+
+// just, because they are needed
+class TestOverflowTruncate : public TDes16Overflow
+    {
+public:
+    virtual void Overflow(TDes16& /* aDes */)
+        {
+        }
+    ;
+    };
+
+#else
+
+class TestOverflowTruncate : public TDes8Overflow
+    {
+public:
+    virtual void Overflow(TDes8 &aDes)
+        {};
+    };
+
+#endif
+
+// just, because they are needed
+class TestOverflowTruncate8 : public TDes8Overflow
+    {
+public:
+    virtual void Overflow(TDes8& /*aDes*/)
+        {
+        }
+    };
+
+
+// RDebug::Print is overwritten, because it is used
+EXPORT_C TInt RDebug::Print( TRefByValue<const TDesC> aFmt,... )
+    {
+    TestOverflowTruncate overflow;
+    VA_LIST list;
+    VA_START(list,aFmt);
+    TBuf<0x100> buf;
+    buf.AppendFormatList( aFmt, list, &overflow );
+#ifdef _UNICODE
+    TPtr8 p( buf.Collapse() );
+
+    // remember it
+    char *context = ( char *)p.Ptr();
+    if( sInUse )
+        {
+        if( sLastHeapContext )
+            {
+            //free it  
+            RTraceAllocator::OwnAllocator()->FreeOwn( sLastHeapContext );
+            sLastHeapContext = NULL;
+            }
+
+        sLastHeapContext = (char *)RTraceAllocator::OwnAllocator()->AllocZOwn( 0x100 );
+        memcpy( sLastHeapContext, context, 0x100 );
+        }
+    // instead of Exec::DebugPrint((TAny*)&p, 0);
+    // RawPrint is used
+    // it could have been this hacked to, but it is not seen necessary
+    // as recording context from Printf/Print seen as enough
+    RDebug::RawPrint( p );
+#else
+    TPtr8 p( buf );
+    // rember it
+    sLastHeapContext = ( char *)p;
+    RDebug::RawPrint( p );
+#endif
+    return 0;
+    }
+
+EXPORT_C void RDebug::Printf( const char* aFmt, ... )
+    {
+    TestOverflowTruncate8 overflow;
+    VA_LIST list;
+    VA_START( list,aFmt );
+    TPtrC8 fmt( (const TText8*)aFmt );
+    TBuf8<0x100> buf;
+    buf.AppendFormatList(fmt, list, &overflow );
+    TPtrC8 p( buf /* (TUint8 *)(buf.Ptr()), 0x100 */);
+
+    // rember it
+    char *context = ( char *)p.Ptr();
+    if( sInUse )
+        {
+        if( sLastHeapContext )
+            {
+            //free it
+            RTraceAllocator::OwnAllocator()->FreeOwn( sLastHeapContext );
+            sLastHeapContext = NULL;
+            }
+        sLastHeapContext = (char *)RTraceAllocator::OwnAllocator()->AllocZOwn( 0x100 );
+        memcpy( sLastHeapContext, context, 0x100 );
+        }
+
+    RDebug::RawPrint( p );
+    }
+
+// If some custom print wanted RawPrint could be hacked,
+// just added for completness
+#if 0
+EXPORT_C void RDebug::RawPrint( const TDesC8& aDes )
+    {
+    // Exec::DebugPrint( ( TAny* )&aDes, 1 );
+    // above should be replaced by custom print
+    }
+
+EXPORT_C void RDebug::RawPrint( const TDesC16& aDes )
+    {
+    TBuf8<0x100> aDes8;
+    if( aDes.Length()>0x100 )
+        {
+        TPtrC ptr( aDes.Ptr(), 0x100 );
+        aDes8.Copy( ptr );
+        }
+    else
+    aDes8.Copy(aDes);
+    // Exec::DebugPrint((TAny*)&aDes8, 1);
+    // above should be replaced by custom print
+    }
+#endif
+
+AllocHeapContext::AllocHeapContext(TAny* aPtr, TInt aSize, char* aText1,
+        AllocHeapContext *aNext)
+    {
+    iPtr = aPtr;
+    iSize = aSize;
+
+    // but we need to copy here  
+    if (aText1 == NULL)
+        {
+        iText1 = NULL;
+        }
+    else
+        {
+        iText1 = (char *)RTraceAllocator::OwnAllocator()->AllocZOwn( 0x100);
+        if (iText1 != NULL)
+            memcpy(iText1, aText1, 0x100);
+        else
+            {
+            // just for testing
+            // in this case 
+            // there is no space to store additional info
+            iText1 = iText1;
+            }
+        }
+
+    iNext = aNext;
+    }
+
+AllocHeapContext::~AllocHeapContext()
+    {
+    if (iText1)
+        {
+        RTraceAllocator::OwnAllocator()->FreeOwn(iText1);
+        iText1 = NULL;
+        }
+    }
+
+PtrAssocArray::PtrAssocArray(RHeap *aHeap)
+    {
+    iHeap = aHeap; //points to in Traceallocator iOwnHeap
+    // not necessary to fill with NULL pointers, as RHeap::Allocz 
+    // does the job already 
+    for (TUint i = 0; i < 65535; i++)
+        {
+        iAHT[i].iInfo = NULL;
+        }
+    }
+
+PtrAssocArray::~PtrAssocArray()
+    {
+    }
+
+// insert an element into the list
+TInt PtrAssocArray::Insert(AllocHeapContext* aAHC)
+    {
+    if ( !aAHC)
+        {
+        return KErrArgument;
+        }
+
+    TUint hashVal = Hash(aAHC->iPtr);
+    // no collision, add to the table
+    if (iAHT[hashVal].iInfo == NULL)
+        {
+        iAHT[hashVal].iInfo = aAHC;
+        }
+    // collision, insert at the beginning of linked list.
+    else
+        {
+        aAHC->iNext = iAHT[hashVal].iInfo;
+        iAHT[hashVal].iInfo = aAHC;
+        }
+    return KErrNone;
+    }
+
+TUint PtrAssocArray::Hash(TAny *aPtr)
+    {
+    TUint val = (TUint)aPtr;
+    // take the middle part as hash value 65536 
+    // different values
+    val = (val & 0x00FFFF00 ) >> 8;
+    return val;
+    }
+
+// find an element in the list
+AllocHeapContext *PtrAssocArray::Find(TAny *aPtr)
+    {
+    if ( !aPtr)
+        return NULL;
+    TUint hashVal = Hash(aPtr);
+    AllocHeapContext *ptr = iAHT[hashVal].iInfo;
+    if (ptr != NULL)
+        {
+        do
+            {
+            if (ptr->iPtr != aPtr)
+                {
+                ptr = ptr->iNext;
+                continue;
+                }
+            else
+                {
+                return ptr;
+                }
+            }
+        while (ptr);
+        }
+    return NULL;
+    }
+
+// remove an element from the list
+TInt PtrAssocArray::Remove(TAny *aPtr)
+    {
+    if ( !aPtr)
+        return KErrArgument;
+    TUint hashVal = Hash(aPtr);
+    AllocHeapContext *ptr = iAHT[hashVal].iInfo;
+    if (ptr != NULL)
+        {
+        AllocHeapContext *prevPtr= NULL;
+        do
+            {
+            if (ptr->iPtr != aPtr)
+                {
+                prevPtr = ptr;
+                ptr = ptr->iNext;
+                continue;
+                }
+            else
+                {
+                // found, we should unlink and free memory          
+                if (prevPtr)
+                    {
+                    prevPtr->iNext = ptr->iNext;
+                    }
+                else
+                    {
+                    //This is first element in linked list.
+                    if (ptr->iNext==NULL)
+                        {
+                        //List should cleared only if this is last element
+                        iAHT[hashVal].iInfo = NULL;
+                        }
+                    else
+                        {
+                        iAHT[hashVal].iInfo = ptr->iNext;
+                        }
+                    }
+                // call destructor
+                ptr->AllocHeapContext::~AllocHeapContext();
+                // deallocate
+                iHeap->Free(ptr);
+
+                return KErrNone;
+                }
+            }
+        while (ptr);
+        }
+    return KErrNotFound;
+    }
+
+void PtrAssocArray::PrintLeaks()
+    {
+    for (TUint i = 0; i < 65536; i++)
+        {
+        AllocHeapContext *ptr = iAHT[i].iInfo;
+        if ( !ptr)
+            continue;
+        do
+            {
+            if (ptr->iText1 != NULL)
+                RDebug::Printf(
+                        "Camera:PrintLeaks ptr: %x, size: %d, context: %s",
+                        ptr->iPtr, ptr->iSize, ptr->iText1);
+            else
+                RDebug::Printf(
+                        "Camera:PrintLeaks ptr: %x, size: %d, context: <<NO CONTEXT>>",
+                        ptr->iPtr, ptr->iSize);
+            ptr = ptr->iNext;
+            }
+        while (ptr);
+        }
+    }
+
+void PtrAssocArray::CleanTables()
+    {
+    // Not really necessary to implement
+
+    // disable code below
+    // by replacing #if 1 by #if 0
+#if 1
+    for (TUint i = 0; i < 65536; i++)
+        {
+        AllocHeapContext *ptr = iAHT[i].iInfo;
+        if ( !ptr)
+            {
+            //Don't continue...
+            continue;
+            }
+        // deallocate the list    
+        AllocHeapContext *nextPtr= NULL;
+        while (ptr) //Is this ever true? 
+            {
+            nextPtr = ptr->iNext;
+            // call destructor
+            ptr->AllocHeapContext::~AllocHeapContext();
+            // deallocate
+            iHeap->Free(ptr);
+            ptr = nextPtr;
+            }
+        }
+#endif    
+    }
+
+
+
+RTraceAllocator::RTraceAllocator(RHeap *aCurrentHeap)
+    {
+    iHeap = aCurrentHeap;
+    iOwnHeap = UserHeap::ChunkHeap( NULL, 1024 * 64, 1024*1024 * 2);
+    iAHM = (PtrAssocArray *)iOwnHeap->AllocZ(sizeof(PtrAssocArray));
+    ::new(iAHM) PtrAssocArray( iOwnHeap );
+    sInUse = ETrue;
+    }
+
+TAny* RTraceAllocator::Alloc(TInt aSize)
+    {
+    TAny *tmp = iHeap->Alloc(aSize);
+
+    sInUse = EFalse;
+    RDebug::Printf("Camera: RTraceAllocator::Alloc %x, %d", ( TUint32 )tmp,
+            aSize);
+    sInUse = ETrue;
+  
+    if (tmp)
+        {
+  
+    AllocHeapContext* ahc = (AllocHeapContext*) ( iOwnHeap->AllocZ(sizeof(AllocHeapContext)) ); 
+        // text from last debug print is added
+        // it can be extended to add more. Timing information for example.
+        ::new(ahc) AllocHeapContext( tmp, aSize, sLastHeapContext );
+        iAHM->Insert(ahc);
+        }
+    else
+        {
+        // can be commented out this, if failed allocations are not interesting
+        // RDebug::Printf("M:Alloc %x, %d", (TUint32) tmp, aSize);
+        }
+    return tmp;
+    }
+
+
+void RTraceAllocator::Free(TAny* aPtr)
+    {
+    if (aPtr)
+        {
+        iAHM->Remove(aPtr);
+        sInUse = EFalse;
+        RDebug::Printf("RTraceAllocator::Free %x", ( TUint32 ) aPtr );
+        sInUse = ETrue;
+        iHeap->Free(aPtr);
+        }
+    }
+
+
+TAny* RTraceAllocator::ReAlloc(TAny* aPtr, TInt aSize, TInt aMode)
+    {
+    TAny *tmp= NULL;
+
+    if (aPtr == NULL)
+        {
+        if (aMode != ENeverMove)
+            {
+            tmp = RTraceAllocator::Alloc(aSize);
+
+            sInUse = EFalse;
+            RDebug::Printf("M:Realloc %x %x %d %x", (TUint32) tmp, aPtr,
+                    aSize, aMode);
+            sInUse = ETrue;
+            return tmp;
+            }
+        else
+            {
+            // Now we are allocating a block which should never move...
+            // Call below could panic USER:42
+            tmp = iHeap->ReAlloc(aPtr, aSize, aMode);
+
+            sInUse = EFalse;
+            RDebug::Printf("M:Realloc %x %x %d %x", (TUint32) tmp, aPtr,
+                    aSize, aMode);
+            sInUse = ETrue;
+
+            if (tmp)
+                {
+            AllocHeapContext *ahc = (AllocHeapContext*) ( iOwnHeap->AllocZ(sizeof(AllocHeapContext)) );
+                // not yet handled if this kind of allocation above fails !
+                // Add last debug print...
+                ::new(ahc) AllocHeapContext( tmp, aSize, sLastHeapContext );
+                iAHM->Insert(ahc);
+                }
+            return tmp;
+            }
+        }
+
+    //aPtr is not NULL. So it is real reallocation or accidentally
+    //pointing a cell -> PANIC
+    tmp = iHeap->ReAlloc(aPtr, aSize, aMode);
+
+    sInUse = EFalse;
+    RDebug::Printf("M:Realloc %x %x %d %x", (TUint32) tmp, aPtr, aSize, aMode);
+    sInUse = ETrue;
+
+    if (tmp)
+        {
+        // Check if information of old allocation has been stored.
+        if (iAHM->Find(aPtr) != NULL)
+            {
+            // remove the info
+            iAHM->Remove(aPtr);
+            }
+        // store new information
+      AllocHeapContext *ahc = (AllocHeapContext*) ( iOwnHeap->AllocZ(sizeof(AllocHeapContext)) );
+        // not yet handled if this kind of allocation above fails !
+        ::new(ahc) AllocHeapContext( tmp, aSize, sLastHeapContext );
+        iAHM->Insert(ahc);
+        }
+
+    return tmp;
+    }
+
+TInt RTraceAllocator::AllocLen(const TAny* aCell) const
+    {
+    // Printing commented out because it cause big delay
+    // when exiting application.
+    /*
+     sInUse = EFalse;
+     RDebug::Printf( "Camera: RTraceAllocator::AllocLen" );
+     sInUse = ETrue;
+     */
+    return iHeap->AllocLen(aCell);
+    }
+
+TInt RTraceAllocator::Compress()
+    {
+    sInUse = EFalse;
+    RDebug::Printf("Camera: RTraceAllocator::Compress");
+    sInUse = ETrue;
+    //This doesn't require AllocHeapContext or iAHM because
+    //Compress doesn't affect sizes of allocated area.
+    return iHeap->Compress();
+    }
+
+void RTraceAllocator::Reset()
+    {
+    sInUse = EFalse;
+    RDebug::Printf("Camera: RTraceAllocator::Reset");
+    sInUse = ETrue;
+    //This should also sync iAHM because otherwise iAHM is showing
+    //freed cells as allocated. Currently not implemented.
+    return iHeap->Reset();
+    }
+
+TInt RTraceAllocator::AllocSize(TInt& aTotalAllocSize) const
+    {
+    sInUse = EFalse;
+    RDebug::Printf("Camera: RTraceAllocator::AllocSize %d", aTotalAllocSize);
+    sInUse = ETrue;
+    return iHeap->AllocSize(aTotalAllocSize);
+    }
+
+TInt RTraceAllocator::Available(TInt& aBiggestBlock) const
+    {
+    TInt t = iHeap->Available(aBiggestBlock);
+    sInUse = EFalse;
+    RDebug::Printf("Camera: RTraceAllocator::Available %d %d", aBiggestBlock,
+            t);
+    sInUse = ETrue;
+    return t;
+    }
+
+TInt RTraceAllocator::DebugFunction(TInt /* aFunc */, TAny* /* a1 */, TAny* /* a2 */)
+    {
+    sInUse = EFalse;
+    RDebug::Printf("Camera: RTraceAllocator::DebugFunction");
+    sInUse = ETrue;
+    return 0;
+    }
+
+#endif //_MEMORY_TRACKING
+#endif //_DEBUG
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCamDocument::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCamDocument* CCamDocument::NewL( CEikApplication& aApp )
+    {
+    CCamDocument* self = NewLC( aApp );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCamDocument::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCamDocument* CCamDocument::NewLC( CEikApplication& aApp )
+    {
+    CCamDocument* self = new( ELeave ) CCamDocument( aApp );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+    
+// Destructor
+CCamDocument::~CCamDocument()
+    {
+    PRINT( _L("Camera => ~CCamDocument") );
+#ifdef CAMERAAPP_PERF_LOG_TRACES	
+    // Shutdown end event cannot be logged to memory logger
+    PERF_EVENT_END_TRACE( EPerfEventApplicationShutdown );
+#endif	
+
+    delete iController;
+
+    // print leaks info
+
+#ifdef _DEBUG
+  
+#ifdef _MEMORY_TRACKING
+    RTraceAllocator& alloc = (RTraceAllocator &)User::Heap();
+    alloc.PrintLeaks();
+    alloc.CleanTables();
+    User::SwitchHeap(alloc.SavedHeap() );
+    alloc.Close();
+    delete &alloc;
+#endif //_MEMORY_TRACKING
+#ifdef _AO_TRACKING
+    // restoring the original scheduler
+    RestoreCurrentAS();
+#endif // _AO_TRACKING
+#endif //_DEBUG
+    PRINT( _L("Camera <= ~CCamDocument") );
+    }
+
+// -----------------------------------------------------------------------------
+// CCamDocument::CreateAppUiL
+// Create the application user interface, and return a pointer to it
+// the framework takes ownership of this object
+// -----------------------------------------------------------------------------
+//
+CEikAppUi* CCamDocument::CreateAppUiL()
+    {
+#ifdef _DEBUG
+#ifdef _AO_TRACKING
+    // replacing the scheduler
+    ReplaceCurrentASL();
+#endif // _AO_TRACKING
+#endif // _DEBUG
+    return new( ELeave ) CCamAppUi( *iController ); 
+    }
+
+// -----------------------------------------------------------------------------
+// CCamDocument::CCamDocument
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CCamDocument::CCamDocument( CEikApplication& aApp )  
+    : CAknDocument( aApp ) 
+    {
+    // No implementation required
+    }
+
+// -----------------------------------------------------------------------------
+// CCamDocument::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCamDocument::ConstructL()
+    {
+#ifdef _DEBUG
+#ifdef _MEMORY_TRACKING
+    // New heap for memory leak information.
+     RHeap& currentHeap = User::Heap();
+     RTraceAllocator *alloc = new RTraceAllocator( &currentHeap );
+     if( alloc )
+       User::SwitchHeap( alloc );
+     //End of memoryleak heap replacer.    
+#endif //_MEMORY_TRACKING
+#endif //_DEBUG
+    
+    PERF_EVENT_START_L1( EPerfEventAppFirstStartup );	
+    // Create the controller.
+    iController = CCamAppController::NewL();
+    }
+
+//  End of File