uifw/AvKon/src/AknIncallStatusBubble.cpp
changeset 0 2f259fa3e83a
child 14 3320e4e6e8bb
child 51 fcdfafb36fe7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknIncallStatusBubble.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,2010 @@
+/*
+* Copyright (c) 2002-2008 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:  Handles incall status bubble drawing.
+*
+*/
+
+
+// SYSTEM INCLUDE FILES
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefmacros.h>
+#endif
+#include    <eikimage.h>
+#include    <eikenv.h>
+#include    <barsread.h>            // Resource reader
+#include    <bautils.h>             // erase
+#include    <avkon.rsg>
+#include    <AknsUtils.h>
+#include    <AknsDrawUtils.h>
+#include    <aknlayoutscalable_apps.cdl.h>
+#include    <layoutmetadata.cdl.h>
+#include    <AknIconUtils.h>
+#include    <featmgr.h>
+#include    <akniconconfig.h>
+#include    <coeaui.h>
+#include    <coemain.h>
+#include    <coreapplicationuisdomainpskeys.h> // KCoreAppUIsAutolockStatus
+
+#include <AknTasHook.h>
+// USER INCLUDE FILES
+#include    "AknIncallStatusBubble.h"
+#include    "AknBitmapAnimation.h"  // Animation definition
+#include    "AknUtils.h"
+#include    "aknappui.h"
+#include    "AknDef.h"
+#include    "aknconsts.h"
+#include    "AknStatuspaneUtils.h"
+
+// CONSTANTS
+
+// There does not seem to be any way to query WSERV wheter TRANSPARENCY option has been
+// defined. We use this constant to decide which way we do things.
+// const TBool KTransparentWindowsUsed = EFalse;  // Disabled at the moment for performance reasons.
+
+const TUid KPhoneAppUid      = { 0x100058B3 };
+const TUid KPhoneViewUid     = { 0x10282D81 };
+const TUid KPhoneVievCommand = { 0x2 }; // forces call handling to foreground
+const TUid KVideoCallUid     = { 0x101F8681 }; 
+
+// Note that some icons are masked and some are non-masked.
+
+enum // Grouped by icon layout...
+    {
+    // Layout1
+    EIndexCallstatusQgn_indi_call_active = 0,
+    EIndexCallstatusQgn_indi_call_active_mask,
+    EIndexCallstatusQgn_indi_call_active_2,
+    EIndexCallstatusQgn_indi_call_active_2_mask,
+    EIndexCallstatusQgn_indi_call_active_cyph_off,
+    EIndexCallstatusQgn_indi_call_active_cyph_off_mask,
+    EIndexCallstatusQgn_indi_call_disconn,
+    EIndexCallstatusQgn_indi_call_disconn_mask,
+    EIndexCallstatusQgn_indi_call_disconn_cyph_off,
+    EIndexCallstatusQgn_indi_call_disconn_cyph_off_mask,
+    EIndexCallstatusQgn_indi_call_held,
+    EIndexCallstatusQgn_indi_call_held_mask,
+    EIndexCallstatusQgn_indi_call_held_cyph_off,
+    EIndexCallstatusQgn_indi_call_held_cyph_off_mask,
+    EIndexCallstatusQgn_indi_call_muted_callsta,
+    EIndexCallstatusQgn_indi_call_muted_callsta_mask,
+    EIndexCallstatusQgn_indi_call_video_callsta,
+    EIndexCallstatusQgn_indi_call_video_callsta_mask,
+    EIndexCallstatusQgn_indi_call_video_callsta_1,
+    EIndexCallstatusQgn_indi_call_video_callsta_1_mask,
+    EIndexCallstatusQgn_indi_call_video_callsta_2,
+    EIndexCallstatusQgn_indi_call_video_callsta_2_mask,
+    EIndexCallstatusQgn_indi_call_active_emergency,
+    EIndexCallstatusQgn_indi_call_active_emergency_mask,
+    EIndexCallstatusQgn_indi_call_video_1,
+    EIndexCallstatusQgn_indi_call_video_1_mask,
+    EIndexCallstatusQgn_indi_call_video_disconn,
+    EIndexCallstatusQgn_indi_call_video_disconn_mask,
+    EIndexCallStatusQgn_indi_call_voip_active,
+    EIndexCallStatusQgn_indi_call_voip_active_mask,
+    EIndexCallStatusQgn_indi_call_voip_active_2,
+    EIndexCallStatusQgn_indi_call_voip_active_2_mask,
+    EIndexCallStatusQgn_indi_call_voip_disconn,
+    EIndexCallStatusQgn_indi_call_voip_disconn_mask,
+    EIndexCallStatusQgn_indi_call_voip_held,
+    EIndexCallStatusQgn_indi_call_voip_held_mask,
+    ELayout1End = EIndexCallStatusQgn_indi_call_voip_held_mask,
+
+    // Layout2
+    EIndexCallstatusQgn_graf_bubble_incall,
+    EIndexCallstatusQgn_graf_bubble_incall_mask,
+    EIndexCallstatusQgn_graf_bubble_incall_disconn,
+    EIndexCallstatusQgn_graf_bubble_incall_disconn_mask,
+    ELayout2End = EIndexCallstatusQgn_graf_bubble_incall_disconn_mask,
+
+    // Layout3
+    EIndexCallstatusQgn_indi_call_cyphering_off,
+    EIndexCallstatusQgn_indi_call_cyphering_off_mask, // not used, but AknIconUtils & SVG needs this to exist
+    //ELayout3End = EIndexCallstatusQgn_indi_call_cyphering_off,
+    ELayout3End = EIndexCallstatusQgn_indi_call_cyphering_off_mask,
+
+    // Layout4
+    EIndexCallstatusQgn_indi_call_data,
+    EIndexCallstatusQgn_indi_call_data_mask, // not used, but AknIconUtils & SVG needs this to exist
+    EIndexCallstatusQgn_indi_call_data_hscsd,
+    EIndexCallstatusQgn_indi_call_data_hscsd_mask, // not used, but AknIconUtils & SVG needs this to exist
+    EIndexCallstatusQgn_indi_call_fax,
+    EIndexCallstatusQgn_indi_call_fax_mask, // not used, but AknIconUtils & SVG needs this to exist
+    //ELayout4End = EIndexCallstatusQgn_indi_call_fax,
+    ELayout4End = EIndexCallstatusQgn_indi_call_fax_mask,
+
+    // Layout5
+    EIndexCallstatusQgn_indi_call_line2,
+    EIndexCallstatusQgn_indi_call_line2_mask, // not used, but AknIconUtils & SVG needs this to exist
+    //ELayout5End = EIndexCallstatusQgn_indi_call_line2
+    ELayout5End = EIndexCallstatusQgn_indi_call_line2_mask
+    };
+
+// Cleanup stack helper.
+
+NONSHARABLE_CLASS( CCleanupGuard ) : public CBase
+    {
+    public:
+        inline CCleanupGuard() {}
+        ~CCleanupGuard();
+    public:
+        inline void SetItem1( CBase* aItem ) {iItem1 = aItem;}
+        inline void SetItem2( CBase* aItem ) {iItem2 = aItem;}
+    private:
+        CBase* iItem1;
+        CBase* iItem2;
+    };
+
+CCleanupGuard::~CCleanupGuard()
+    {
+    delete iItem1;
+    delete iItem2;
+    }
+
+// ==== CIncallAnim  CLASS ======================
+
+/**
+* Helper class for animation control
+*/
+NONSHARABLE_CLASS( CIncallAnim ) : public CCoeControl
+    {
+    public:
+
+    enum
+        {
+        EDefaultCallAnim,
+        EVoipCallAnim,
+        EVideoCallAnim
+        };
+
+
+    public:
+        void ConstructL( CIncallStatusBubble& aImages );
+        ~CIncallAnim();
+        void MakeVisible( TBool aVisible );
+
+        void ClearAnimation();
+        void SetAnimationL( CIncallStatusBubble& aImages,
+                            TInt aCallAnimType = EDefaultCallAnim );
+        void SetAnimationType( TInt aCallAnimType );
+        void CreateBackGroundImageL( const CFbsBitmap* aBubbleBitmap,
+                                     const CFbsBitmap* aBubbleMask,
+                                     TRect aBubbleRect );
+
+    private:
+        void UpdateAnimationL( CIncallStatusBubble& aImages,
+                               TInt aCallAnimType = EDefaultCallAnim );
+        void SizeChanged();
+        void Draw( const TRect& aRect ) const;
+    private:
+        CAknBitmapAnimation* iIndiAnim;
+        CAknBitmapAnimation* iIndiVoIPAnim;
+        CAknBitmapAnimation* iIndiVideoAnim;
+        CFbsBitmap* iAnimBackGroundImage;
+        mutable TBool iIsRunning;
+        mutable TBool iIsVoIPRunning;
+        mutable TBool iIsVideoRunning;
+        TInt iCallAnimType;
+    };
+
+// Constructor
+void CIncallAnim::ConstructL( CIncallStatusBubble& aImages )
+    {
+    iCallAnimType = EDefaultCallAnim;
+
+    iAnimBackGroundImage = new ( ELeave ) CFbsBitmap();
+
+    SetAnimationL( aImages );
+
+    ActivateL();
+
+    CCoeControl::MakeVisible( EFalse );
+    }
+
+// Destructor
+CIncallAnim::~CIncallAnim()
+    {
+    delete iIndiAnim;
+    delete iIndiVoIPAnim;
+    delete iIndiVideoAnim;
+    delete iAnimBackGroundImage;
+    }
+
+void CIncallAnim::CreateBackGroundImageL(const CFbsBitmap* aBubbleBitmap, const CFbsBitmap* aBubbleMask, TRect aBubbleRect)
+    {
+    if (iAnimBackGroundImage && aBubbleBitmap && aBubbleMask)
+        {
+        CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL(iAnimBackGroundImage);
+        CleanupStack::PushL(destinationDevice);
+
+        CFbsBitGc* destinationGc;
+        User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
+
+        TRect rect = Rect();
+        rect.Move(-aBubbleRect.iTl);
+        destinationGc->BitBltMasked(TPoint(0,0), aBubbleBitmap, rect, aBubbleMask, ETrue);
+
+        delete destinationGc;
+        CleanupStack::PopAndDestroy(destinationDevice);
+        }
+    }
+
+// Position/Size changed
+void CIncallAnim::SizeChanged()
+    {
+    TRect rect( Rect() );
+
+    if ( !iIndiAnim || !iIndiVoIPAnim || !iIndiVideoAnim )
+        {
+        return;
+        }
+
+    if ( Rect().IsEmpty() )
+        return;
+
+    if ( ( rect.Size() != iIndiAnim->Size() ) ||
+         ( rect.Size() != iIndiVoIPAnim->Size() ) ||
+         ( rect.Size() != iIndiVideoAnim->Size() ))
+        {
+        AknIconConfig::TPreferredDisplayMode mode;
+        AknIconConfig::PreferredDisplayMode(mode, AknIconConfig::EImageTypeOffscreen);
+        iAnimBackGroundImage->Create(
+            Size(),
+            mode.iBitmapMode);
+        }
+    iIndiAnim->SetRect( rect );
+    iIndiVoIPAnim->SetRect( rect );
+    iIndiVideoAnim->SetRect( rect );
+    }
+
+// Draws the animation
+void CIncallAnim::Draw( const TRect& /*aRect*/ ) const
+    {
+    CAknBitmapAnimation* ok = NULL;
+    switch (iCallAnimType)
+        {
+        case EDefaultCallAnim:
+            ok = iIndiAnim;
+            break;
+        case EVoipCallAnim:
+            ok = iIndiAnim;
+            break;
+        case EVideoCallAnim:
+            ok = iIndiAnim;
+            break;
+        default:
+            ok = NULL;
+            break;
+        }
+    
+    if ( !ok )
+        {
+        return;
+        }
+
+
+    // Background is no more copied from screen because it does not work very well.
+    // Instead we use the image that has been set.
+    if (iAnimBackGroundImage)
+        {
+        // Create frame for background
+        CBitmapFrameData* data = NULL;
+        TRAPD( error , ( data = CBitmapFrameData::NewL() ) );
+        if ( error != KErrNone || data == NULL )
+            {
+            iIsRunning = EFalse;
+            iIsVoIPRunning = EFalse;
+            return;
+            }
+
+        data->SetBitmapsOwnedExternally( ETrue );
+        data->SetBitmap( iAnimBackGroundImage );
+        data->SetInterval( -1 );
+
+        // Set frame to animation
+        CBitmapAnimClientData* animData;
+
+        if ( iCallAnimType == EVoipCallAnim )
+            {
+            animData = iIndiVoIPAnim->BitmapAnimData();
+            }
+        else if ( iCallAnimType == EVideoCallAnim )
+            {
+            animData = iIndiVideoAnim->BitmapAnimData();
+            }
+        else
+            {
+            animData = iIndiAnim->BitmapAnimData();
+            }
+
+        animData->SetBackgroundFrame( data );
+
+        // This is a const function so mutable cast is needed
+        // to change member variables
+        CIncallAnim* mutableThis =
+            MUTABLE_CAST( CIncallAnim* , this );
+
+        // Start animation - we can't do a thing if this fails
+        if ( iCallAnimType == EVoipCallAnim )
+            {
+            TRAP( error , iIndiVoIPAnim->StartAnimationL(EFalse) );
+            mutableThis->iIsVoIPRunning = ETrue;
+            mutableThis->iIsRunning = EFalse;
+            mutableThis->iIsVideoRunning = EFalse;
+            }
+        else if ( iCallAnimType == EVideoCallAnim )
+            {
+            TRAP( error , iIndiVideoAnim->StartAnimationL(EFalse) );
+            mutableThis->iIsVoIPRunning = EFalse;
+            mutableThis->iIsVideoRunning = ETrue;
+            mutableThis->iIsRunning = EFalse;
+            }
+        else
+            {
+            TRAP( error , iIndiAnim->StartAnimationL(EFalse) );
+            mutableThis->iIsVoIPRunning = EFalse;
+            mutableThis->iIsRunning = ETrue;
+            mutableThis->iIsVideoRunning = EFalse;
+            }
+        }
+    }
+
+// Creates new animation frames
+void CIncallAnim::SetAnimationL( CIncallStatusBubble& aImages, TInt aCallAnimType )
+    {
+    iCallAnimType = aCallAnimType;
+
+    // Create new animation
+    iIndiAnim = CAknBitmapAnimation::NewL();
+    iIndiAnim->SetContainerWindowL( *this );
+    iIndiVoIPAnim = CAknBitmapAnimation::NewL();
+    iIndiVoIPAnim->SetContainerWindowL( *this );
+    iIndiVideoAnim = CAknBitmapAnimation::NewL();
+    iIndiVideoAnim->SetContainerWindowL( *this );
+
+    TInt resourceReaderId = 0;
+    resourceReaderId = R_BUBBLEMANAGER_ALERTING_ANIM;
+    TResourceReader rr;
+    iCoeEnv->CreateResourceReaderLC( rr , resourceReaderId );
+    iIndiAnim->ConstructFromResourceL(rr);
+    CleanupStack::PopAndDestroy(); // rr
+
+    resourceReaderId = R_BUBBLEMANAGER_ALERTING_VOIP_ANIM;
+    TResourceReader rr2;
+    iCoeEnv->CreateResourceReaderLC( rr2 , resourceReaderId );
+    iIndiVoIPAnim->ConstructFromResourceL(rr2);
+    CleanupStack::PopAndDestroy(); // rr2
+
+    resourceReaderId = R_BUBBLEMANAGER_ALERTING_VIDEO_ANIM;
+    TResourceReader rr3;
+    iCoeEnv->CreateResourceReaderLC( rr3 , resourceReaderId );
+    iIndiVideoAnim->ConstructFromResourceL(rr3);
+    CleanupStack::PopAndDestroy(); // rr3
+
+    UpdateAnimationL( aImages, EDefaultCallAnim );// Normal CS call.
+    UpdateAnimationL( aImages, EVoipCallAnim ); // VoIP call.
+    UpdateAnimationL( aImages, EVideoCallAnim ); // Video call.
+    }
+
+void CIncallAnim::UpdateAnimationL( CIncallStatusBubble& aImages, TInt aCallAnimType )
+    {
+    // Clear old data:
+    CBitmapAnimClientData* animData;
+    if ( aCallAnimType == EVoipCallAnim )
+        {
+        animData = iIndiVoIPAnim->BitmapAnimData();
+        }
+    else if (iCallAnimType == EVideoCallAnim)
+        {
+        animData = iIndiVideoAnim->BitmapAnimData();
+        }
+    else
+        {
+        animData = iIndiAnim->BitmapAnimData();
+        }
+
+    animData->ResetFrameArray();
+
+    // Create frame 1
+    CEikImage* image1 = new (ELeave) CEikImage;
+    image1->SetPictureOwnedExternally( ETrue );
+    CleanupStack::PushL( image1 );
+
+    if ( aCallAnimType == EVoipCallAnim )
+        {
+        aImages.GetImage(
+            *image1,
+            EIndexCallStatusQgn_indi_call_voip_active,
+            EIndexCallStatusQgn_indi_call_voip_active_mask
+            );
+        }
+    else if (iCallAnimType == EVideoCallAnim)
+        {
+        aImages.GetImage(
+            *image1,
+            EIndexCallstatusQgn_indi_call_video_callsta_1,
+            EIndexCallstatusQgn_indi_call_video_callsta_1_mask
+            );
+        }
+    else
+        {
+        aImages.GetImage(
+            *image1,
+            EIndexCallstatusQgn_indi_call_active,
+            EIndexCallstatusQgn_indi_call_active_mask
+            );
+        }
+
+    CBitmapFrameData* frame1 = CBitmapFrameData::NewL(
+        MUTABLE_CAST( CFbsBitmap*, image1->Bitmap() ),
+        MUTABLE_CAST( CFbsBitmap*, image1->Mask() ) );
+
+    frame1->SetInterval( KErrNotFound );
+    frame1->SetBitmapsOwnedExternally( ETrue );
+    CleanupStack::PushL( frame1 );
+
+    animData->AppendFrameL( frame1 ); // Takes ownership
+
+    CleanupStack::Pop( frame1 );
+    CleanupStack::PopAndDestroy( image1 );
+
+    // Create frame 2
+    CEikImage* image2 = new (ELeave) CEikImage;
+    image2->SetPictureOwnedExternally( ETrue );
+    CleanupStack::PushL( image2 );
+
+    if ( aCallAnimType == EVoipCallAnim )
+        {
+        aImages.GetImage(
+            *image2,
+            EIndexCallStatusQgn_indi_call_voip_active_2,
+            EIndexCallStatusQgn_indi_call_voip_active_2_mask
+            );
+        }
+    else if (iCallAnimType == EVideoCallAnim)
+        {
+        aImages.GetImage(
+            *image2,
+            EIndexCallstatusQgn_indi_call_video_callsta_2,
+            EIndexCallstatusQgn_indi_call_video_callsta_2_mask
+            );
+        }
+    else
+        {
+        aImages.GetImage(
+            *image2,
+            EIndexCallstatusQgn_indi_call_active_2,
+            EIndexCallstatusQgn_indi_call_active_2_mask
+            );
+        }
+
+    CBitmapFrameData* frame2 = CBitmapFrameData::NewL(
+        MUTABLE_CAST( CFbsBitmap*, image2->Bitmap() ),
+        MUTABLE_CAST( CFbsBitmap*, image2->Mask() ) );
+
+    frame2->SetInterval( KErrNotFound );
+    frame2->SetBitmapsOwnedExternally( ETrue );
+    CleanupStack::PushL( frame2 );
+
+    animData->AppendFrameL( frame2 ); // Takes ownership
+
+    CleanupStack::Pop( frame2 );
+    CleanupStack::PopAndDestroy( image2 );
+    }
+
+void CIncallAnim::SetAnimationType( TInt aCallAnimType )
+    {
+    iCallAnimType = aCallAnimType;
+    }
+
+// Clears current animation
+void CIncallAnim::ClearAnimation()
+    {
+    if ( iIndiAnim )
+        {
+        CBitmapAnimClientData* animData = iIndiAnim->BitmapAnimData();
+        animData->ResetFrameArray();
+        }
+    delete iIndiAnim;
+    iIndiAnim = NULL;
+
+    if ( iIndiVoIPAnim )
+        {
+        CBitmapAnimClientData* animData = iIndiVoIPAnim->BitmapAnimData();
+        animData->ResetFrameArray();
+        }
+    delete iIndiVoIPAnim;
+    iIndiVoIPAnim = NULL;
+
+    if ( iIndiVideoAnim )
+        {
+        CBitmapAnimClientData* animData = iIndiVideoAnim->BitmapAnimData();
+        animData->ResetFrameArray();
+        }
+    delete iIndiVideoAnim;
+    iIndiVideoAnim = NULL;
+
+    }
+
+// Make visible
+void CIncallAnim::MakeVisible( TBool aVisible )
+    {
+    if ( IsVisible() && !aVisible && iIndiAnim && iIsRunning )
+        {
+        TInt err = iIndiAnim->CancelAnimation();
+        if ( err == KErrNone )
+            {
+            iIsRunning = EFalse;
+            }
+        }
+
+    if ( IsVisible() && !aVisible && iIndiVoIPAnim && iIsVoIPRunning )
+        {
+        TInt err = iIndiVoIPAnim->CancelAnimation();
+        if ( err == KErrNone )
+            {
+            iIsVoIPRunning = EFalse;
+            }
+        }
+
+    if ( IsVisible() && !aVisible && iIndiVideoAnim && iIsVideoRunning )
+        {
+        TInt err = iIndiVideoAnim->CancelAnimation();
+        if ( err == KErrNone )
+            {
+            iIsVideoRunning = EFalse;
+            }
+        }
+
+    CCoeControl::MakeVisible( aVisible ); // a call to parent's method
+    }
+
+// ==== CIncallAnim  CLASS ======================
+
+/**
+* Helper class for muted icon (has its own window)
+*/
+NONSHARABLE_CLASS(CIncallMuted) : public CCoeControl
+    {
+    public:
+        void ConstructL( CCoeControl& aParent );
+        ~CIncallMuted();
+
+        void SetMutedImage(
+            const CFbsBitmap* aBitmap ,
+            const CFbsBitmap* aMask );
+
+        TInt CountComponentControls() const;
+        CCoeControl* ComponentControl(TInt aIndex) const;
+    private:
+        void SizeChanged();
+        void HandlePointerEventL(const TPointerEvent& aPointerEvent);
+
+    private:
+        CEikImage* iMutedImage;
+        CIncallStatusBubble *iIncallStatusBubble;
+    };
+
+// Constructor
+void CIncallMuted::ConstructL( CCoeControl& aParent )
+    {
+    SetContainerWindowL( aParent );
+
+    iIncallStatusBubble = ( CIncallStatusBubble* ) &aParent;
+
+    iMutedImage = new( ELeave ) CEikImage;
+    iMutedImage->SetContainerWindowL( *this );
+    iMutedImage->SetPictureOwnedExternally( ETrue );
+    iMutedImage->MakeVisible( EFalse );
+
+    SetComponentsToInheritVisibility();
+    Window().SetPointerGrab( ETrue );
+    EnableDragEvents();
+    }
+
+// Destructor
+CIncallMuted::~CIncallMuted()
+    {
+    delete iMutedImage;
+    }
+
+// Sets images
+void CIncallMuted::SetMutedImage(
+    const CFbsBitmap* aBitmap ,
+    const CFbsBitmap* aMask )
+    {
+    iMutedImage->SetPicture( aBitmap , aMask );
+    SizeChanged();
+    }
+
+// Count component control
+TInt CIncallMuted::CountComponentControls() const
+    {
+    return 1;
+    }
+
+// Component control
+CCoeControl* CIncallMuted::ComponentControl( TInt /*aIndex*/ ) const
+    {
+    return iMutedImage;
+    }
+
+// New size is checked.
+void CIncallMuted::SizeChanged()
+    {
+    if ( !iMutedImage )
+        {
+        return;
+        }
+
+    iMutedImage->SetRect( Rect() );
+
+    CFbsBitmap* bitmap = (CFbsBitmap*)iMutedImage->Bitmap();
+    if ( bitmap )
+        {
+        AknIconUtils::SetSize( bitmap, Size() );
+        }
+    }
+
+
+void CIncallMuted::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+    {
+    CCoeControl::HandlePointerEventL( aPointerEvent );
+
+    iIncallStatusBubble->HandlePointerEventL( aPointerEvent );
+    }
+
+// ================ CIncallStatusBubble CLASS ===============
+
+// ================= MEMBER FUNCTIONS =======================
+
+// Constructor
+CIncallStatusBubble::CIncallStatusBubble() : iOrder( CompareSkinnedData )
+    {
+    }
+
+// NewL
+CIncallStatusBubble* CIncallStatusBubble::NewL( const TRect& aRect )
+    {
+    CIncallStatusBubble* self = new ( ELeave ) CIncallStatusBubble;
+    CleanupStack::PushL( self );
+    self->ConstructL( aRect );
+    CleanupStack::Pop();
+    AKNTASHOOK_ADDL( self, "CIncallStatusBubble" );
+    return self;
+    }
+
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::ConstructL(const TRect& aRect)
+// EPOC two phased constructor
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::ConstructL( const TRect& aRect )
+    {
+    iMyWindowGroup=RWindowGroup( iCoeEnv->WsSession() );
+    User::LeaveIfError( iMyWindowGroup.Construct( (TUint32)&iMyWindowGroup,
+                                                   EFalse ) );
+    iMyWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityMedium );
+    CreateWindowL( &iMyWindowGroup );
+
+    // Load bitmaps to an array
+    iBitmaps = new ( ELeave ) CArrayPtrFlat<CFbsBitmap>( 4 );
+    LoadImagesL();
+
+    // Create skinned animation
+    iSmallIndiAnim = new( ELeave ) CIncallAnim;
+    iSmallIndiAnim->SetContainerWindowL( *this );
+    iSmallIndiAnim->ConstructL( *this );
+
+    // call indication
+    iSmallCallIndication = CreateNewEikImageL();
+
+    // bubble icon
+    iBubble = CreateNewEikImageL();
+
+    // type indicatiors
+    iTypeIndication1 = CreateNewEikImageL();
+    iTypeIndication2 = CreateNewEikImageL();
+
+    // skinned muted icon
+    iMutedIcon = new(ELeave) CIncallMuted;
+    iMutedIcon->ConstructL( *this );
+    CEikImage* tmpMutedImage = new(ELeave) CEikImage;
+    CleanupStack::PushL( tmpMutedImage );
+    tmpMutedImage->SetPictureOwnedExternally( ETrue );
+    GetImage(
+        *tmpMutedImage,
+        EIndexCallstatusQgn_indi_call_muted_callsta,
+        EIndexCallstatusQgn_indi_call_muted_callsta_mask
+        );
+    iMutedIcon->SetMutedImage(tmpMutedImage->Bitmap(), tmpMutedImage->Mask());
+    CleanupStack::PopAndDestroy( tmpMutedImage );
+    iMutedIcon->MakeVisible( EFalse );
+
+    // Cyph off image
+    iCyphOffIcon = CreateNewEikImageL();
+    iPressedDown = EFalse; 
+    // finnish the job
+    MakeVisible( EFalse );
+    SetRect( aRect );
+    Window().SetPointerGrab( ETrue );
+    EnableDragEvents();
+
+    ActivateL();
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::CreateNewEikImageL
+//
+// ---------------------------------------------------------
+//
+CEikImage* CIncallStatusBubble::CreateNewEikImageL() const
+    {
+    CEikImage* newImage = new( ELeave ) CEikImage;
+    CleanupStack::PushL( newImage );
+    newImage->SetContainerWindowL( *this );
+    newImage->SetPictureOwnedExternally( ETrue );
+    newImage->SetPicture( NULL );
+    newImage->MakeVisible( EFalse );
+    CleanupStack::Pop(); // newImage
+    return newImage;
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadImagesL
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::LoadImagesL()
+    {
+    // These need to be loaded in the same order as defined in the
+    // enumeration in the beginning of this file.
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_active,
+        EMbmCallstatusQgn_indi_call_active_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_active_2,
+        EMbmCallstatusQgn_indi_call_active_2_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_active_cyph_off,
+        EMbmCallstatusQgn_indi_call_active_cyph_off_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_disconn,
+        EMbmCallstatusQgn_indi_call_disconn_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_disconn_cyph_off,
+        EMbmCallstatusQgn_indi_call_disconn_cyph_off_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_held,
+        EMbmCallstatusQgn_indi_call_held_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_held_cyph_off,
+        EMbmCallstatusQgn_indi_call_held_cyph_off_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_muted_callsta,
+        EMbmCallstatusQgn_indi_call_muted_callsta_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_video_callsta,
+        EMbmCallstatusQgn_indi_call_video_callsta_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_video_callsta_1,
+        EMbmCallstatusQgn_indi_call_video_callsta_1_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_video_callsta_2,
+        EMbmCallstatusQgn_indi_call_video_callsta_2_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_active_emergency,
+        EMbmCallstatusQgn_indi_call_active_emergency_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_video_1,
+        EMbmCallstatusQgn_indi_call_video_1_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_video_disconn,
+        EMbmCallstatusQgn_indi_call_video_disconn_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_voip_active,
+        EMbmCallstatusQgn_indi_call_voip_active_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_voip_active_2,
+        EMbmCallstatusQgn_indi_call_voip_active_2_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_voip_disconn,
+        EMbmCallstatusQgn_indi_call_voip_disconn_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_indi_call_voip_held,
+        EMbmCallstatusQgn_indi_call_voip_held_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_graf_bubble_incall,
+        EMbmCallstatusQgn_graf_bubble_incall_mask );
+
+    LoadImageL(
+        EMbmCallstatusQgn_graf_bubble_incall_disconn,
+        EMbmCallstatusQgn_graf_bubble_incall_disconn_mask );
+
+    LoadImageL( EMbmCallstatusQgn_indi_call_cyphering_off );
+
+    LoadImageL( EMbmCallstatusQgn_indi_call_data );
+
+    LoadImageL( EMbmCallstatusQgn_indi_call_data_hscsd );
+
+    LoadImageL( EMbmCallstatusQgn_indi_call_fax );
+
+    LoadImageL( EMbmCallstatusQgn_indi_call_line2 );
+    }
+
+
+// Destructor
+CIncallStatusBubble::~CIncallStatusBubble()
+    {
+    AKNTASHOOK_REMOVE();
+    delete iMutedIcon;
+    delete iSmallCallIndication;
+    delete iSmallIndiAnim;
+    delete iTypeIndication1;
+    delete iTypeIndication2;
+    delete iCyphOffIcon;
+    delete iBubble;
+
+    iSkins.ResetAndDestroy();
+    delete iSkinnedColourBitmap;
+
+    if ( iBitmaps )
+        {
+        iBitmaps->ResetAndDestroy( );
+        delete iBitmaps;
+        }
+
+    iMyWindowGroup.Close();
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SizeChanged()
+// Called by framework when the view size is changed
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SizeChanged()
+    {
+    // For performance optimization purposes we do not continue if
+    // we are not visible. Assumed that SetIncallBubbleFlags() causes
+    // this method to be called again.
+    if (!IsVisible() && !(iFlags & ESBVisible))
+        return;
+
+    TRect rect( Rect() );
+    TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+
+    // Set componets to right places
+
+    TAknWindowLineLayout layout1(
+        AknLayoutScalable_Apps::popup_call_status_window_g1(
+            isLandscape ).LayoutLine() );
+
+    TAknWindowLineLayout layout2(
+        AknLayoutScalable_Apps::popup_call_status_window_g2(
+            isLandscape ).LayoutLine() );
+
+    TAknWindowLineLayout layout3(
+        AknLayoutScalable_Apps::popup_call_status_window_g3( isLandscape ).LayoutLine() );
+
+    TAknWindowLineLayout layout4(
+        AknLayoutScalable_Apps::call_type_pane_g1().LayoutLine() );
+
+    TAknWindowLineLayout layout5(
+        AknLayoutScalable_Apps::call_type_pane_g2().LayoutLine() );
+
+    AknLayoutUtils::LayoutImage( iBubble, rect, layout1 );
+
+    AknLayoutUtils::LayoutControl( iSmallCallIndication, rect, layout2 );
+
+    AknLayoutUtils::LayoutControl( iSmallIndiAnim, rect, layout2 );
+
+    AknLayoutUtils::LayoutControl( iMutedIcon, rect, layout2 );
+
+    TAknLayoutRect callTypeIndicationLayoutRect;
+    callTypeIndicationLayoutRect.LayoutRect(
+        rect,
+        AknLayoutScalable_Apps::call_type_pane( isLandscape ) );
+    TRect callTypeIndicationRect( callTypeIndicationLayoutRect.Rect() );
+    
+    TBool hideTypeIndication = isLandscape && !AknStatuspaneUtils::HDLayoutActive();
+    	
+    if ( iFlags & ESBVideo )
+        {
+        // video indicator is different size than others
+        AknLayoutUtils::LayoutControl( iTypeIndication1, rect,  layout2 );
+        }
+    else
+        {
+        if ( hideTypeIndication )
+            {
+            // Not shown in landscape, because there's not enough space.
+            TRect nullRect( 0, 0, 0, 0 );
+            iTypeIndication1->SetRect( nullRect );
+            iTypeIndication2->SetRect( nullRect );
+            iCyphOffIcon->SetRect( nullRect );
+            }
+        else
+            {
+            AknLayoutUtils::LayoutControl( iTypeIndication1,
+                                           callTypeIndicationRect,
+                                           layout4 );
+
+            AknLayoutUtils::LayoutControl( iTypeIndication2,
+                                           callTypeIndicationRect,
+                                           layout5 );
+
+            AknLayoutUtils::LayoutControl( iCyphOffIcon,
+                                           rect,
+                                           layout3 );
+            }
+        }
+
+    // Bitmaps must be validated (size is set) before they can be used.
+    TAknLayoutRect layoutRect;
+
+    TInt ii;
+
+    // Layout group 1
+    layoutRect.LayoutRect( rect, layout2 );
+    for ( ii = EIndexCallstatusQgn_indi_call_active; ii <= ELayout1End; ii++ )
+        {
+        AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+        }
+
+    if ( iSmallCallIndication )
+        {
+        CFbsBitmap* bitmap = (CFbsBitmap*)iSmallCallIndication->Bitmap();
+        if ( bitmap )
+            {
+            AknIconUtils::SetSize( bitmap, iSmallCallIndication->Rect().Size() );
+            }
+        }
+
+
+    // Layout group 2
+    layoutRect.LayoutRect( rect, layout1 );
+    for ( ii = EIndexCallstatusQgn_graf_bubble_incall; ii < ELayout2End; ii++ )
+        {
+        AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+        }
+
+    if ( iBubble )
+        {
+        CFbsBitmap* bitmap = (CFbsBitmap*)iBubble->Bitmap();
+        if ( bitmap )
+            {
+            AknIconUtils::SetSize( bitmap, iBubble->Rect().Size() );
+            }
+        }
+
+
+    // Layout group 3
+    layoutRect.LayoutRect( rect, layout3 );
+    for ( ii = EIndexCallstatusQgn_indi_call_cyphering_off; ii <= ELayout3End; ii++ )
+        {
+        if ( hideTypeIndication )
+            {
+            // Not shown in landscape, because there's not enough space.
+            AknIconUtils::SetSize( iBitmaps->At(ii), TSize(0,0) );
+            }
+        else
+            {
+            AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+            }
+        }
+
+    if ( iCyphOffIcon )
+        {
+        CFbsBitmap* bitmap = (CFbsBitmap*)iCyphOffIcon->Bitmap();
+        if ( bitmap )
+            {
+            if ( hideTypeIndication )
+                {
+                // Not shown in landscape, because there's not enough space.
+                AknIconUtils::SetSize( bitmap, TSize(0,0) );
+                }
+            else
+                {
+                AknIconUtils::SetSize( bitmap, iCyphOffIcon->Rect().Size() );
+                }
+            }
+        }
+
+
+    // Layout group 4
+    layoutRect.LayoutRect( callTypeIndicationRect, layout4 );
+    for ( ii = EIndexCallstatusQgn_indi_call_data; ii <= ELayout4End; ii++ )
+        {
+        if ( hideTypeIndication )
+            {
+            // Not shown in landscape, because there's not enough space.
+            AknIconUtils::SetSize( iBitmaps->At(ii), TSize(0,0) );
+            }
+        else
+            {
+            AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+            }
+        }
+
+    if ( iTypeIndication1 )
+        {
+        CFbsBitmap* bitmap = (CFbsBitmap*)iTypeIndication1->Bitmap();
+        if ( bitmap )
+            {
+            if ( hideTypeIndication )
+                {
+                // Not shown in landscape, because there's not enough space.
+                AknIconUtils::SetSize( bitmap, TSize(0,0) );
+                }
+            else
+                {
+                AknIconUtils::SetSize(bitmap, iTypeIndication1->Rect().Size());
+                }
+            }
+        }
+
+
+    // Layout group 5
+    layoutRect.LayoutRect( callTypeIndicationRect, layout5 );
+    for ( ii = EIndexCallstatusQgn_indi_call_line2; ii <= ELayout5End; ii++ )
+        {
+        if ( hideTypeIndication )
+            {
+            // Not shown in landscape, because there's not enough space.
+            AknIconUtils::SetSize( iBitmaps->At(ii), TSize(0,0) );
+            }
+        else
+            {
+            AknIconUtils::SetSize(iBitmaps->At(ii), layoutRect.Rect().Size());
+            }
+        }
+
+    if ( iTypeIndication2 )
+        {
+        CFbsBitmap* bitmap = (CFbsBitmap*)iTypeIndication2->Bitmap();
+        if ( bitmap )
+            {
+            if ( hideTypeIndication )
+                {
+                // Not shown in landscape, because there's not enough space.
+                AknIconUtils::SetSize( bitmap, TSize(0,0) );
+                }
+            else
+                {
+                AknIconUtils::SetSize(bitmap, iTypeIndication2->Rect().Size());
+                }
+            }
+        }
+
+    Window().SetTransparencyAlphaChannel();
+    Window().SetBackgroundColor( ~0 );
+
+    // Update background of animation
+    if ( iSmallIndiAnim && iBubble && iBubble->Bitmap() && iBubble->Mask() )
+        TRAP_IGNORE( iSmallIndiAnim->CreateBackGroundImageL(
+            iBubble->Bitmap(),
+            iBubble->Mask(),
+            TRect( iBubble->Position(), iBubble->Bitmap()->SizeInPixels() ) ) );
+
+    // Make draw
+    DrawDeferred();
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::CountComponentControls() const
+//
+//
+// ---------------------------------------------------------
+//
+TInt CIncallStatusBubble::CountComponentControls() const
+    {
+    return 7; // bubble, small indi, anim , 2* type icons, cyph off and muted
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::ComponentControl(TInt aIndex) const
+//
+// ---------------------------------------------------------
+//
+CCoeControl* CIncallStatusBubble::ComponentControl(TInt aIndex) const
+    {
+    switch ( aIndex )
+        {
+        case 0:
+            return iBubble;
+        case 1:
+            return iSmallCallIndication;
+        case 2:
+            return iTypeIndication1;
+        case 3:
+            return iTypeIndication2;
+        case 4:
+            return iCyphOffIcon;
+        case 5:
+            return iSmallIndiAnim;
+        case 6:
+            return iMutedIcon;
+        default:
+            return NULL;
+        }
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::Draw
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::Draw(const TRect& /*aRect*/) const
+    {
+    CWindowGc&  gc = SystemGc();
+    gc.Clear();
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SetFlags
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SetFlags( const TInt& aFlags )
+    {
+    iFlags = aFlags;
+    SelectImages();
+    SizeChanged();
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::Flags
+// Two versions to eliminate compiler warnings
+// ---------------------------------------------------------
+//
+#ifdef __WINS__
+const TInt CIncallStatusBubble::Flags()
+    {
+    return iFlags;
+    }
+#else
+TInt CIncallStatusBubble::Flags()
+    {
+    return iFlags;
+    }
+#endif
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SetFaded
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SetFaded(TBool aFaded)
+    {
+    if (!COMPARE_BOOLS(Window().IsFaded(), aFaded))
+        {
+        iMyWindowGroup.SetFaded(
+            aFaded, RWindowTreeNode::EFadeIncludeChildren);
+        }
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SelectImages
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SelectImages()
+    {
+    if ( ! ( iFlags & ESBVisible ) )
+        {
+        iSmallCallIndication->MakeVisible( EFalse );
+        iBubble->MakeVisible( EFalse );
+        iSmallIndiAnim->MakeVisible( EFalse );
+        iTypeIndication1->MakeVisible( EFalse );
+        iTypeIndication2->MakeVisible( EFalse );
+        iCyphOffIcon->MakeVisible( EFalse );
+        iMutedIcon->MakeVisible( EFalse );
+        return;
+        }
+
+    TRect rect( Rect() );
+
+    // first set call indication and bubble image
+    TInt indiBitmap = KErrNotFound;
+    TInt indiMask = KErrNotFound;
+    iSmallIndiAnim->MakeVisible( EFalse );
+
+
+    GetImage(
+        *iBubble,
+        EIndexCallstatusQgn_graf_bubble_incall,
+        EIndexCallstatusQgn_graf_bubble_incall_mask );
+    iBubble->MakeVisible( ETrue );
+
+    switch ( iFlags & (ESBAlerting|ESBActive|ESBOnHold|ESBDisconnected ) ) // two last bits
+        {
+        case ESBAlerting:
+        case ESBActive:
+            if ( iFlags & ESBVoIPCall &&
+                FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+                {
+                indiBitmap = EIndexCallStatusQgn_indi_call_voip_active;
+                indiMask = EIndexCallStatusQgn_indi_call_voip_active_mask;
+                }
+
+            else if ( iFlags & ESBVideo )
+                {
+                indiBitmap = EIndexCallstatusQgn_indi_call_video_callsta_1;
+                indiMask = EIndexCallstatusQgn_indi_call_video_callsta_1_mask;
+                }
+
+            else
+                {
+                indiBitmap = EIndexCallstatusQgn_indi_call_active;
+                indiMask = EIndexCallstatusQgn_indi_call_active_mask;
+                }
+            break;
+        case ESBOnHold:
+            if ( iFlags & ESBVoIPCall &&
+                FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+                {
+                indiBitmap = EIndexCallStatusQgn_indi_call_voip_held;
+                indiMask = EIndexCallStatusQgn_indi_call_voip_held_mask;
+                }
+            else
+                {
+                indiBitmap = EIndexCallstatusQgn_indi_call_held;
+                indiMask = EIndexCallstatusQgn_indi_call_held_mask;
+                }
+            break;
+        case ESBDisconnected:
+            if ( iFlags & ESBVoIPCall &&
+                FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+                {
+                indiBitmap = EIndexCallStatusQgn_indi_call_voip_disconn;
+                indiMask = EIndexCallStatusQgn_indi_call_voip_disconn_mask;
+                }
+
+            else if ( iFlags & ESBVideo )
+                {
+                indiBitmap = EIndexCallstatusQgn_indi_call_video_disconn;
+                indiMask = EIndexCallstatusQgn_indi_call_video_disconn_mask;
+                }
+
+            else
+                {
+                indiBitmap = EIndexCallstatusQgn_indi_call_disconn;
+                indiMask = EIndexCallstatusQgn_indi_call_disconn_mask;
+                }
+
+            GetImage(
+                *iBubble,
+                EIndexCallstatusQgn_graf_bubble_incall_disconn,
+                EIndexCallstatusQgn_graf_bubble_incall_disconn_mask );
+            break;
+        default:
+            _LIT(KCallStatus,"CallStatus");
+            User::Panic(KCallStatus , 0 );
+            break;
+        }
+
+    // Cyph off
+    if ( iFlags & ESBNoCiphering )
+        {
+        GetImage(
+            *iCyphOffIcon,
+            EIndexCallstatusQgn_indi_call_cyphering_off );
+        iCyphOffIcon->MakeVisible( ETrue );
+        }
+    else
+        {
+        iCyphOffIcon->MakeVisible( EFalse );
+        }
+
+    // Muted icon
+    if ( iFlags & ESBMuted )
+        {
+        iMutedIcon->MakeVisible( ETrue );
+        }
+    else
+        {
+        iMutedIcon->MakeVisible( EFalse );
+        }
+
+    // Animation
+    if ( (iFlags & (ESBAlerting|ESBActive|ESBOnHold|ESBDisconnected )) == ESBAlerting )
+        {
+        if ( iFlags & ESBVoIPCall &&
+            FeatureManager::FeatureSupported( KFeatureIdCommonVoip ))
+            {
+            iSmallIndiAnim->SetAnimationType( CIncallAnim::EVoipCallAnim );  // We have VoIP call.
+            }
+        else if (iFlags & ESBVideo)
+            {
+            iSmallIndiAnim->SetAnimationType( CIncallAnim::EVideoCallAnim );  // We have Video call.
+            }
+        else
+            {
+            iSmallIndiAnim->SetAnimationType( CIncallAnim::EDefaultCallAnim ); // We have normal CS call.
+            }
+
+        iSmallIndiAnim->MakeVisible( ETrue );
+        }
+    else
+        {
+        iSmallIndiAnim->MakeVisible( EFalse );
+        }
+
+
+    // Emergency call
+    if ( (iFlags & (ESBAlerting|ESBActive|ESBOnHold|ESBDisconnected )) == ESBActive &&
+         (iFlags & ESBEmergency) )
+        {
+        indiBitmap = EIndexCallstatusQgn_indi_call_active_emergency;
+        indiMask = EIndexCallstatusQgn_indi_call_active_emergency_mask;
+        }
+
+
+    if ( indiBitmap != KErrNotFound )
+        {
+        GetImage(
+            *iSmallCallIndication,
+            indiBitmap ,
+            indiMask );
+
+        iSmallCallIndication->MakeVisible( ETrue );
+        }
+
+
+
+    // set type pane
+    TInt picture1 = KErrNotFound;
+    TInt picture2 = KErrNotFound;
+
+    TInt mask1 = KErrNotFound;
+
+    if ( iFlags & ESBFax )
+        {
+        picture1 = EIndexCallstatusQgn_indi_call_fax;
+        }
+    else if ( iFlags & ESBDataHscsd )
+        {
+        picture1 = EIndexCallstatusQgn_indi_call_data_hscsd;
+        }
+    else if ( iFlags & ESBData )
+        {
+        picture1 = EIndexCallstatusQgn_indi_call_data;
+        }
+    else if ( iFlags & ESBVideo )
+        {
+        // type pane is used for video call, it should not be need to use other
+        // other types with video call
+        picture1 = EIndexCallstatusQgn_indi_call_video_callsta;
+        mask1 = EIndexCallstatusQgn_indi_call_video_callsta_mask;
+        }
+
+    if ( iFlags & ESBLine2 )
+        {
+        if ( picture1 == KErrNotFound )
+            {
+            picture1 = EIndexCallstatusQgn_indi_call_line2;
+            }
+        else
+            {
+            picture2 = EIndexCallstatusQgn_indi_call_line2;
+            }
+        }
+
+    if ( picture1 != KErrNotFound )
+        {
+        TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+
+        GetImage(
+            *iTypeIndication1,
+            picture1,
+            mask1);
+
+        if ( iFlags & ESBVideo )
+            {
+            // video indicator is different size than others
+            AknLayoutUtils::LayoutControl(
+                iTypeIndication1,
+                rect,
+                AknLayoutScalable_Apps::popup_call_status_window_g2(
+                    isLandscape ).LayoutLine() );
+
+            // muted icon is never shown with video call
+            iMutedIcon->MakeVisible( EFalse );
+
+            // line2 indication never shown with video call
+            picture2 = KErrNotFound;
+            }
+        else
+            {
+            if ( isLandscape )
+                {
+                // Not shown in landscape.
+                iTypeIndication1->SetRect( TRect( 0, 0, 0, 0 ) );
+                }
+            else
+                {
+                TAknLayoutRect callTypeIndicationRect;
+                callTypeIndicationRect.LayoutRect(
+                    rect,
+                    AknLayoutScalable_Apps::call_type_pane() );
+                AknLayoutUtils::LayoutControl(
+                    iTypeIndication1,
+                    callTypeIndicationRect.Rect(),
+                    AknLayoutScalable_Apps::call_type_pane_g1().LayoutLine() );
+                }
+            }
+
+        // "Video hold" does not have its own graphics, so we show it differently for now.
+        if ( iFlags & ESBVideo &&
+           ((iFlags & ( ESBAlerting | ESBActive | ESBOnHold | ESBDisconnected )) != ESBOnHold))
+            {
+            iTypeIndication1->MakeVisible( EFalse );
+            }
+        else
+            {
+            iTypeIndication1->MakeVisible( ETrue );
+            }
+
+
+        if ( picture2 != KErrNotFound )
+            {
+            GetImage( *iTypeIndication2,
+                      picture2 );
+            iTypeIndication2->MakeVisible( ETrue );
+
+            }
+        else
+            {
+            iTypeIndication2->MakeVisible( EFalse );
+            }
+
+        }
+    else
+        {
+        iTypeIndication1->MakeVisible( EFalse );
+        iTypeIndication2->MakeVisible( EFalse );
+        }
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SetRect
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SetRect( const TRect& aRect )
+    {
+    CCoeControl::SetRect( aRect );
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::MapEnumToSkin
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::MapEnumToSkin(
+    const TInt aBmIcon, TAknsItemID& aID )
+    {
+    switch ( aBmIcon )
+        {
+        // Skinned bitmap:
+        case EIndexCallstatusQgn_indi_call_active:
+            aID = KAknsIIDQgnIndiCallActive;
+            break;
+        case EIndexCallstatusQgn_indi_call_disconn:
+            aID = KAknsIIDQgnIndiCallDisconn;
+            break;
+        case EIndexCallstatusQgn_indi_call_held:
+            aID = KAknsIIDQgnIndiCallHeld;
+            break;
+        case EIndexCallstatusQgn_indi_call_active_2:
+            aID = KAknsIIDQgnIndiCallActive2;
+            break;
+        case EIndexCallstatusQgn_indi_call_muted_callsta:
+            aID = KAknsIIDQgnIndiCallMutedCallsta;
+            break;
+        case EIndexCallstatusQgn_graf_bubble_incall:
+            aID = KAknsIIDQgnGrafBubbleIncall;
+            break;
+        case EIndexCallstatusQgn_graf_bubble_incall_disconn:
+            aID = KAknsIIDQgnGrafBubbleIncallDisconn;
+            break;
+        case EIndexCallStatusQgn_indi_call_voip_active:
+            aID = KAknsIIDQgnIndiCallVoipActive;
+            break;
+        case EIndexCallStatusQgn_indi_call_voip_active_2:
+            aID = KAknsIIDQgnIndiCallVoipActive2;
+            break;
+        case EIndexCallStatusQgn_indi_call_voip_disconn:
+            aID = KAknsIIDQgnIndiCallVoipDisconn;
+            break;
+        case EIndexCallStatusQgn_indi_call_voip_held:
+            aID = KAknsIIDQgnIndiCallVoipHeld;
+            break;
+        case EIndexCallstatusQgn_indi_call_video_callsta:
+            aID = KAknsIIDQgnIndiCallVideoCallsta;
+            break;
+        case EIndexCallstatusQgn_indi_call_video_callsta_1:
+            aID = KAknsIIDQgnIndiCallVideoCallsta1;
+            break;
+        case EIndexCallstatusQgn_indi_call_video_callsta_2:
+            aID = KAknsIIDQgnIndiCallVideoCallsta2;
+            break;
+        case EIndexCallstatusQgn_indi_call_video_disconn:
+            aID = KAknsIIDQgnIndiCallVideoCallstaDisconn;
+            break;
+
+        // Colour change:
+        case EIndexCallstatusQgn_indi_call_data:
+        case EIndexCallstatusQgn_indi_call_data_hscsd:
+        case EIndexCallstatusQgn_indi_call_fax:
+        case EIndexCallstatusQgn_indi_call_line2:
+        case EIndexCallstatusQgn_indi_call_cyphering_off:
+            aID = KAknsIIDQsnTextColors;
+            break;
+        default:
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::GetSkinForIcon
+//
+// ---------------------------------------------------------
+//
+CAknsItemData* CIncallStatusBubble::GetSkinForIcon(
+    const TInt aBmIcon )
+    {
+    CAknsItemData* data = NULL;
+
+    TAknsItemID skinId = KAknsIIDNone;
+    MapEnumToSkin( aBmIcon, skinId );
+    if ( skinId == KAknsIIDNone )
+        {
+        return NULL;
+        }
+
+    SSkinnedImage skinnedImage;
+    skinnedImage.iId = skinId;
+
+    TInt index = iSkins.FindInOrder( &skinnedImage, iOrder );
+    if ( index != KErrNotFound )
+        {
+        data = iSkins[ index ]->iItemData;
+        }
+    else
+        {
+        TRAP_IGNORE( data = LoadAndAppendSkinL( skinId ) );
+        }
+    return data;
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadAndAppendSkinL
+//
+// ---------------------------------------------------------
+//
+CAknsItemData* CIncallStatusBubble::LoadAndAppendSkinL(
+    const TAknsItemID& aId )
+    {
+    SSkinnedImage* newImage = new(ELeave) SSkinnedImage;
+    CleanupStack::PushL( newImage );
+
+    newImage->iId = aId;
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    newImage->iItemData = skin->CreateUncachedItemDataL( aId );
+
+    User::LeaveIfError( iSkins.InsertInOrder( newImage, iOrder ) );
+    CleanupStack::Pop( newImage ); // Ownership was given to iSkins array
+
+    return newImage->iItemData;
+    }
+
+// ---------------------------------------------------------------------------
+// CIncallStatusBubble::GetSkin
+// ---------------------------------------------------------------------------
+//
+TBool CIncallStatusBubble::GetSkin( CEikImage& aImage, const TInt aBmIcon )
+    {
+    CAknsItemData* data    = GetSkinForIcon( aBmIcon );
+
+    CFbsBitmap* bitmap     = NULL;
+    CFbsBitmap* bitmapMask = NULL;
+
+    if ( data )
+        {
+        switch ( data->Type() )
+            {
+            case EAknsITMaskedBitmap:
+                {
+                CAknsMaskedBitmapItemData* maskedBitmapData =
+                    static_cast< CAknsMaskedBitmapItemData* >( data );
+                bitmapMask = maskedBitmapData->Mask();
+                }
+                // Flow through
+            case EAknsITBitmap:
+                {
+                CAknsBitmapItemData* bitmapData =
+                    static_cast< CAknsBitmapItemData* >( data );
+                bitmap = bitmapData->Bitmap();
+                }
+                break;
+            case EAknsITColorTable:
+                {
+                // If the color for call bubble texts is not defined in the
+                // current skin, use gray.
+                TRgb colour( KRgbGray );
+                MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+                AknsUtils::GetCachedColor(
+                    skin,
+                    colour,
+                    KAknsIIDQsnTextColors,
+                    EAknsCIQsnTextColorsCG51 );
+
+                // Load the coloured bitmap if not already loaded.
+                if ( !iSkinnedColourBitmap )
+                    {
+                    // Color bitmaps are not anymore supported by scalable
+                    // skin server, we create our own color bitmap here.
+                    TRAP_IGNORE( iSkinnedColourBitmap = CreateSkinnedColourBitmapL() );
+                    }
+                // If found, use the full colour bitmap as the image and
+                // use the "real" bitmap" as the mask.
+                if ( iSkinnedColourBitmap )
+                    {
+                    bitmap     = iSkinnedColourBitmap;
+                    bitmapMask = iBitmaps->At( aBmIcon );
+                    }
+                }
+
+            default:
+                {
+                break;
+                }
+            }
+        }
+
+    if ( bitmap )
+        {
+        aImage.SetBitmap( bitmap );
+        aImage.SetMask( bitmapMask ); // Might be NULL
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::CompareSkinnedData
+//
+// ---------------------------------------------------------
+//
+TInt CIncallStatusBubble::CompareSkinnedData(
+    const SSkinnedImage& aSkin1, const SSkinnedImage& aSkin2 )
+    {
+    return aSkin1.iId.iMinor-aSkin2.iId.iMinor ?
+        aSkin1.iId.iMinor-aSkin2.iId.iMinor :
+        aSkin1.iId.iMajor-aSkin2.iId.iMajor;
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadImageL
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::LoadImageL( TInt aBitmapId )
+    {
+    CFbsBitmap* bitmap;
+    CFbsBitmap* mask;
+
+    CCleanupGuard* guard = new( ELeave ) CCleanupGuard;
+    CleanupStack::PushL( guard );
+
+    AknIconUtils::CreateIconL(
+        bitmap, mask, KCallStatusBitmapFile, aBitmapId, aBitmapId ); // use bitmap id for both mask and bitmap because of 1-bit icons
+
+    guard->SetItem1( bitmap );
+    guard->SetItem2( mask );
+
+    iBitmaps->AppendL( mask );
+    guard->SetItem2( NULL ); // mask
+    iBitmaps->AppendL( bitmap );
+    guard->SetItem1( NULL ); // bitmap
+
+    CleanupStack::PopAndDestroy(); // guard
+
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadImageL
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::LoadImageL( TInt aBitmapId, TInt aMaskId )
+    {
+    CFbsBitmap* bitmap;
+    CFbsBitmap* mask;
+
+    CCleanupGuard* guard = new( ELeave ) CCleanupGuard;
+    CleanupStack::PushL( guard );
+
+    AknIconUtils::CreateIconL(
+        bitmap, mask, KCallStatusBitmapFile, aBitmapId, aMaskId );
+
+    guard->SetItem1( bitmap );
+    guard->SetItem2( mask );
+
+    iBitmaps->AppendL( bitmap );
+    guard->SetItem1( NULL ); // bitmap
+    iBitmaps->AppendL( mask );
+    guard->SetItem2( NULL ); // mask
+
+    CleanupStack::PopAndDestroy(); // guard
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::GetImage
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::GetImage(
+    CEikImage& aImage,
+    const TInt& aImageId,
+    const TInt aImageMaskId )
+    {
+    if ( GetSkin( aImage, aImageId ) )
+        {
+        return;
+        }
+
+    aImage.SetBitmap( iBitmaps->At( aImageId ) );
+    if ( aImageMaskId != KErrNotFound )
+        {
+        aImage.SetMask( iBitmaps->At( aImageMaskId ) );
+        }
+    }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::HandleResourceChange
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::HandleResourceChange( TInt aType )
+    {
+    if ( aType == KAknsMessageSkinChange ||
+         aType == KEikDynamicLayoutVariantSwitch )
+        {
+        // Clear all handles
+        iSmallCallIndication->SetPicture( NULL );
+        iBubble->SetPicture( NULL );
+        iTypeIndication1->SetPicture( NULL );
+        iTypeIndication2->SetPicture( NULL );
+        iCyphOffIcon->SetPicture( NULL );
+        
+        iMutedIcon->SetMutedImage( NULL, NULL );
+
+        iSmallIndiAnim->MakeVisible( EFalse );
+        iSmallIndiAnim->ClearAnimation();
+
+        // Delete old skins
+        iSkins.ResetAndDestroy();
+        delete iSkinnedColourBitmap;
+        iSkinnedColourBitmap = NULL;
+
+        // Update muted icon
+        CEikImage* tmpMutedImage = new CEikImage;
+        if ( tmpMutedImage )
+            {
+            tmpMutedImage->SetPictureOwnedExternally( ETrue );
+            GetImage(
+                *tmpMutedImage,
+                EIndexCallstatusQgn_indi_call_muted_callsta,
+                EIndexCallstatusQgn_indi_call_muted_callsta_mask
+                );
+            iMutedIcon->SetMutedImage(
+                tmpMutedImage->Bitmap(), tmpMutedImage->Mask() );
+            delete tmpMutedImage;
+            }
+
+        // Update animation
+        TInt err = KErrNone;
+        if ( iFlags & ESBVoIPCall &&
+            FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+            {
+            TRAP( err, iSmallIndiAnim->SetAnimationL( *this, CIncallAnim::EVoipCallAnim ) );
+            }
+        else if (iFlags & ESBVideo)
+            {
+            TRAP( err, iSmallIndiAnim->SetAnimationL( *this, CIncallAnim::EVideoCallAnim ) );
+            }
+        else
+            {
+            TRAP( err, iSmallIndiAnim->SetAnimationL( *this, CIncallAnim::EDefaultCallAnim ) );
+            }
+
+        if ( err )
+            {
+            iSmallIndiAnim->ClearAnimation();
+            }
+
+        // Get the other items:
+        SelectImages();
+        SizeChanged();
+        return;
+        }
+
+    CCoeControl::HandleResourceChange(aType);
+    }
+
+
+// ----------------------------------------------------------------------------
+// CIncallStatusBubble::HandlePointerEventL
+// ----------------------------------------------------------------------------
+//
+void CIncallStatusBubble::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+    {
+    // the tap event shall be igored when the keyboard is locked
+    TInt autolockState = EAutolockOff;
+    RProperty::Get( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, autolockState );
+    TPoint pdOffset( 3, 3 );  // Move icon to a little for "pressed" effect
+     if ( !Window().IsFaded() && 
+          AknLayoutUtils::PenEnabled() && 
+          autolockState <= EAutolockOff ) 
+         { 
+         if ( ( aPointerEvent.iType == TPointerEvent::EButton1Down || 
+                aPointerEvent.iType == TPointerEvent::EDrag ) && 
+              Rect().Contains( aPointerEvent.iPosition ) ) 
+             { 
+             // Draw  down effects. 
+             if ( ! iPressedDown ) 
+                 { 
+                 GetImage(
+                     *iBubble,
+                     EIndexCallstatusQgn_graf_bubble_incall_disconn,
+                     EIndexCallstatusQgn_graf_bubble_incall_disconn_mask );
+
+                 TRect newRect = Rect();
+
+                 newRect.Move( PositionRelativeToScreen() + pdOffset );
+
+                 SetRect( newRect );
+
+                 iPressedDown = ! iPressedDown; 
+                 } 
+             } 
+         else if ( aPointerEvent.iType == TPointerEvent::EDrag || 
+                   aPointerEvent.iType == TPointerEvent::EButton1Up ) 
+             { 
+             // Clear pressed down effects. 
+               if ( iPressedDown ) 
+                   { 
+                 GetImage(
+                     *iBubble,
+                     EIndexCallstatusQgn_graf_bubble_incall,
+                     EIndexCallstatusQgn_graf_bubble_incall_mask );
+
+                 TRect newRect = Rect();
+
+                 newRect.Move( PositionRelativeToScreen() - pdOffset );
+
+                 SetRect( newRect );
+
+                   iPressedDown = !iPressedDown; 
+                   } 
+               
+               if ( aPointerEvent.iType == TPointerEvent::EButton1Up && 
+                    Rect().Contains( aPointerEvent.iPosition ) ) 
+                   { 
+                   
+                   CCoeEnv* coeEnv = CCoeEnv::Static();
+                   CCoeAppUi* appUi = NULL;
+                   if ( coeEnv )
+                       {
+                       appUi = coeEnv->AppUi();
+                       }
+                   
+                   if ( appUi )
+                       {
+                       if ( ( iFlags & ESBVideo ) && ( iFlags & ESBActive ) )
+                           {
+                           TVwsViewId viewId( KVideoCallUid, KVideoCallUid );
+                           appUi->CreateActivateViewEventL(viewId, KNullUid, KNullDesC8());
+                           }
+                       else
+                           {
+                           TVwsViewId diallerView( KPhoneAppUid, KPhoneViewUid );
+                           appUi->CreateActivateViewEventL( diallerView,  KPhoneVievCommand, KNullDesC8() );
+                           }
+                       }
+                   }
+             }
+        }
+    else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
+        {
+        CEikMenuBar* menuBar = CEikonEnv::Static()->AppUiFactory()->MenuBar();            
+        if( menuBar && menuBar->IsVisible() )
+            {
+            //Stops displaying the uifactory's menu bar.
+            menuBar->StopDisplayingMenuBar();  
+            }
+        else
+            {
+            //Stops displaying the application's menu bar.
+            CEikonEnv::Static()->EikAppUi()->StopDisplayingMenuBar();
+            }
+        }
+    }
+
+CFbsBitmap* CIncallStatusBubble::CreateSkinnedColourBitmapL()
+    {
+    TSize size( Rect().Size() );
+    if ( size == TSize( 0, 0 ) )
+    {
+        return NULL;
+    }
+
+    TRgb colour( KRgbGray );
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    AknsUtils::GetCachedColor(
+        skin,
+        colour,
+        KAknsIIDQsnTextColors,
+        EAknsCIQsnTextColorsCG51 );
+
+    CFbsBitmap* destinationBitmap = new (ELeave) CFbsBitmap();
+    CleanupStack::PushL( destinationBitmap );
+    User::LeaveIfNull( destinationBitmap );
+
+    User::LeaveIfError( destinationBitmap->Create( size, EColor16M ) );
+
+    CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL( destinationBitmap );
+    CleanupStack::PushL( destinationDevice );
+
+    CFbsBitGc* destinationGc;
+    User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
+
+    destinationGc->SetPenColor( colour );
+    destinationGc->SetPenStyle( CGraphicsContext::ESolidPen );
+    destinationGc->SetBrushColor( colour );
+    destinationGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
+    destinationGc->DrawRect( TRect( size ) );
+
+    delete destinationGc;
+    CleanupStack::PopAndDestroy( destinationDevice );
+    CleanupStack::Pop( destinationBitmap );
+
+    return destinationBitmap;
+    }
+
+// End of File