mmsengine/mmsmessage/src/mmsownnumber.cpp
changeset 0 72b543305e3a
child 2 0bf1d54f37d9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsengine/mmsmessage/src/mmsownnumber.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,546 @@
+/*
+* Copyright (c) 2005 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:   Check id any of given numbers is caller's own number
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include    "mmsownnumber.h"
+#include    "mmsgenutils.h"
+#include    <e32std.h>
+#include    <badesca.h>
+#include    <centralrepository.h>
+#include    <telconfigcrkeys.h>
+
+#include    <CVPbkContactManager.h>
+#include    <VPbkContactStoreUris.h>
+#include    <CVPbkContactStoreUriArray.h>
+#include    <MVPbkContactLinkArray.h>
+#include    <MVPbkContactLink.h>
+#include    <TVPbkContactStoreUriPtr.h>
+#include    <MVPbkContactStoreList.h>
+#include    <MVPbkContactOperationBase.h>
+#include    <MVPbkStoreContact.h>
+#include    <MVPbkFieldType.h>
+#include    <MVPbkContactFieldTextData.h>
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMmsOwnNumber::CMmsOwnNumber
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMmsOwnNumber::CMmsOwnNumber()
+    : CActive( EPriorityNormal ),
+    iIndex( KErrNotFound )
+    {
+    CActiveScheduler::Add(this);
+    }
+
+// -----------------------------------------------------------------------------
+// CMmsOwnNumber::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMmsOwnNumber::ConstructL( RFs* aFs )
+    {
+    iFs = aFs;
+    
+    // The function is supposed to get a descriptor with packed URIs.
+    // As we only have one URI we assume it is packed enough
+    CVPbkContactStoreUriArray* storeArray = CVPbkContactStoreUriArray::NewLC();
+    TVPbkContactStoreUriPtr uriPtr( VPbkContactStoreUris::SimGlobalOwnNumberUri() );
+    storeArray->AppendL( uriPtr );
+    
+    // TEST TRY ALSO DEFAULT DATABASE AS SIM DATABASE DOES NOT WORK IN WINS
+    
+/*    
+    TVPbkContactStoreUriPtr uriPtr2( VPbkContactStoreUris::DefaultCntDbUri() );
+    storeArray->AppendL( uriPtr2 );
+*/    
+    // END OF TEST
+    
+    iNumberOfStores = storeArray->Count();
+    iNumberOfOpenStores = iNumberOfStores; // otimistic
+    
+    // Open the database with the URI that specifies our own number
+    iContactManager = CVPbkContactManager::NewL( *storeArray, aFs );
+    
+	CleanupStack::PopAndDestroy( storeArray );
+	
+	iContactList = &(iContactManager->ContactStoresL());
+	
+	//Let's find the number of digits to match
+    iDigitsToMatch = KMmsNumberOfDigitsToMatch ;
+
+    CRepository* repository = NULL;
+    TInt error = KErrNone;
+    TRAP( error, repository = CRepository::NewL( KCRUidTelConfiguration ));
+    if ( error == KErrNone)
+        {
+        error = repository->Get( KTelMatchDigits, iDigitsToMatch );
+        delete repository;
+        if( error != KErrNone )
+            {
+            iDigitsToMatch=KMmsNumberOfDigitsToMatch;
+            }
+    	}
+    }
+
+// -----------------------------------------------------------------------------
+// CMmsOwnNumber::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMmsOwnNumber* CMmsOwnNumber::NewL( RFs* aFs )
+    {
+    CMmsOwnNumber* self = new( ELeave ) CMmsOwnNumber;
+    
+    CleanupStack::PushL( self );
+    self->ConstructL( aFs );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+    
+// Destructor
+CMmsOwnNumber::~CMmsOwnNumber()
+    {
+	Cancel();
+	delete iContact;
+	delete iOperation;
+	delete iResultArray;
+	delete iContactManager;
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::DoCancel
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::DoCancel()
+    {
+	delete iOperation;
+	iOperation = NULL;
+	TRequestStatus* s=&iStatus;
+    User::RequestComplete(s, KErrCancel);
+    }
+
+// ---------------------------------------------------------
+// CMmsOwnNumber::RunL
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::RunL()
+    {
+    
+    delete iOperation;
+    iOperation = NULL;
+    
+    if ( iStatus != KErrNone )
+        {
+#ifdef _DEBUG
+        TMmsGenUtils::Log( _L("OwnNumber: RunL status: %d "), iStatus.Int() );
+#endif
+
+       	// Exit current scheduler loop, resuming execution of the StartL() function
+      	iActiveSchedulerWait.AsyncStop();
+      	return;
+        }
+    
+    switch ( iState )
+        {
+        case EMmsOwnNumberOpening:
+            {
+            iState = EMmsOwnNumberSearching;
+            iMatch = EFalse;
+            SearchL();
+            break;
+            }
+        case EMmsOwnNumberSearching:
+            {
+            iState = EMmsOwnNumberCheckingDuplicates;
+            CheckDuplicatesL();
+            break;
+            }
+        case EMmsOwnNumberCheckingDuplicates:
+            {
+            iState = EMmsOwnNumberIdle;
+            iContactList->CloseAll( *this );
+            break;
+            }
+        default:
+            {
+            break;
+            }
+        }
+    if ( !IsActive() )
+        {
+       	// Exit current scheduler loop, resuming execution of the StartL() function
+        delete iResultArray;
+        iResultArray = NULL;
+      	iActiveSchedulerWait.AsyncStop();
+        }
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::RunError
+// ---------------------------------------------------------
+//
+
+#ifdef _DEBUG
+TInt CMmsOwnNumber::RunError( TInt aError )
+#else
+TInt CMmsOwnNumber::RunError( TInt /* aError */ )
+#endif
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber: RunError: %d "), aError );
+    TMmsGenUtils::Log( _L("OwnNumber: state: %d "), iState );
+#endif
+    delete iOperation;
+    iOperation = NULL;
+    delete iResultArray;
+    iResultArray = NULL;
+  	iActiveSchedulerWait.AsyncStop();	//Exit current scheduler loop, resuming execution of the Start() function
+  	return KErrNone;
+    }
+
+// ---------------------------------------------------------
+// CMmsOwnNumber::FindCompleteL
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::FindCompleteL( MVPbkContactLinkArray* aResults )
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::FindCompleteL ") );
+#endif
+    iResultArray = aResults;
+    iContactToMatch = iResultArray->Count(); // point beyound the array
+    iMatch = EFalse;
+    
+    // check the result array for matches and set our index accordingly
+    if ( iResultArray->Count() == 0 )
+        {
+        // we are responsible for the results array if we did not leave.
+        delete iResultArray;
+        iResultArray = 0;
+        // no match found - this is not our own number
+        iNumberToMatch++;
+        if ( iNumberToMatch < iNumberList->MdcaCount() )
+            {
+            // try the next one
+            iState = EMmsOwnNumberOpening;
+            }
+        }
+    else
+        {
+        // we found at least one match.
+        // What do we do now...
+        // Analyse the result in detail or just say "This is our own number"...
+        
+        // First approximation: Say this is our own.
+        // Actually exact match cases should be checked, too (short number)
+        // And possible email match, but that needs a different search function
+                
+        // save the match and return to RunL
+        // It will stop the active scheduler and allow the code to return to caller
+        iIndex = iNumberToMatch;
+        if ( iNumberList->MdcaPoint( iNumberToMatch ).Length() < iDigitsToMatch ||
+            iResultArray->Count() > 1 )
+            {
+            // need exact match, start from first item in the array
+            iContactToMatch = 0;
+            }
+        }
+    TRequestStatus* s=&iStatus;
+    User::RequestComplete( s, KErrNone );
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::FindFailed
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::FindFailed(TInt aError)
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber: FindFailed: %d "), aError );
+#endif
+    iIndex = aError;
+ 	TRequestStatus* s=&iStatus;
+    iNumberToMatch++;
+    if ( iNumberToMatch < iNumberList->MdcaCount() )
+        {
+        // try the next one
+        iState = EMmsOwnNumberOpening;
+        }
+    User::RequestComplete( s, KErrNone );
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::OpenComplete
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::OpenComplete()
+    {
+    // if opening fails, StoreUnavailable is called
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::OpenCompleteL") );
+#endif
+	TRequestStatus* s=&iStatus;
+    User::RequestComplete( s, KErrNone );
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::StoreReady
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::StoreReady(MVPbkContactStore& /*aContactStore*/)
+    {
+    // Nothing to do here
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::StoreReady") );
+#endif
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::StoreUnavailable
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::StoreUnavailable(MVPbkContactStore& /*aContactStore*/, TInt /*aReason*/)
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::StoreUnavailable") );
+#endif
+    iNumberOfOpenStores--;
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::HandleStoreEventL
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::HandleStoreEventL(
+    MVPbkContactStore& /*aContactStore*/, 
+    TVPbkContactStoreEvent /*aStoreEvent*/)
+    {
+    
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::VPbkSingleContactOperationComplete
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::VPbkSingleContactOperationComplete(
+    MVPbkContactOperationBase& /*aOperation*/,
+    MVPbkStoreContact* aContact)    
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::VPbkSingleContactOperationComplete") );
+#endif
+    iContact = aContact;
+    
+    MVPbkBaseContactFieldCollection& fields = iContact->Fields();
+    
+    TInt fieldCount = fields.FieldCount();
+    
+    TInt i;
+    
+/*    
+    const TInt maxMatchPriority = iContactManager->FieldTypes().MaxMatchPriority();
+*/    
+    for ( i = 0; i < fieldCount && !iMatch ; i++ )
+        {
+        const MVPbkBaseContactField& field = fields.FieldAt( i );
+/*        
+        const MVPbkFieldType* fieldType = field.MatchFieldType( maxMatchPriority );
+*/        
+        const MVPbkContactFieldData& fieldData =  field.FieldData();
+        
+        // I could not figure out how to check the actual field type
+        // (phone number or email or what), we must try all text fields
+        if ( fieldData.DataType() == EVPbkFieldStorageTypeText )
+            {
+            const MVPbkContactFieldTextData& textData = MVPbkContactFieldTextData::Cast(fieldData);
+            // Now we finally have the data we can compare with our own data
+            if ( textData.Text().Compare( iNumberList->MdcaPoint( iNumberToMatch ) ) == 0 )
+                {
+                // exact match.
+                iMatch = ETrue;
+                }
+            }
+        }
+    
+    delete iContact;
+    iContact = NULL;
+    
+    iContactToMatch++;
+    
+    if ( !iMatch && iContactToMatch < iResultArray->Count() )
+        {
+        iState = EMmsOwnNumberSearching;
+        }
+    else if ( !iMatch )
+        {
+        // This was not an exact match
+        iIndex = KErrNotFound;
+        delete iResultArray;
+        iResultArray = 0;
+        iNumberToMatch++;
+        if ( iNumberToMatch < iNumberList->MdcaCount() )
+            {
+            // try the next one if any left
+            iState = EMmsOwnNumberOpening;
+            }
+        }
+    else
+        {
+        // keep LINT happy.
+        }
+        
+ 	TRequestStatus* s=&iStatus;
+    User::RequestComplete( s, KErrNone );
+    }
+
+// ---------------------------------------------------------
+// CMmsOwnNumber::
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::VPbkSingleContactOperationFailed(
+    MVPbkContactOperationBase& /*aOperation*/, 
+#ifdef _DEBUG
+    TInt aError)
+#else    
+    TInt /*aError*/)
+#endif
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber: ContactOperationFailed: %d "), aError );
+#endif
+    // If not found iMatch stays false
+    iContactToMatch++;
+    
+ 	TRequestStatus* s=&iStatus;
+    User::RequestComplete( s, KErrNone );
+    }
+
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::StartL
+// ---------------------------------------------------------
+//
+TInt CMmsOwnNumber::StartL( const CDesCArray& aNumberList )
+    {
+    iIndex = KErrNotFound;
+    delete iOperation;
+    iOperation = NULL;
+    
+    if ( aNumberList.MdcaCount() <= 0)
+        {
+        return iIndex; // no contacts, not found
+        }
+    iNumberList = &aNumberList;
+    iNumberToMatch = 0;
+    iContactToMatch = 0;
+        
+    iContactList->OpenAllL( *this );
+        
+    // We must set ourselves to pending because we don't give our status to anybody
+    // When search is complete, the functions call our callbacks, and we complete ourselves
+    iState = EMmsOwnNumberOpening;
+    iStatus = KRequestPending;
+	SetActive();
+	iActiveSchedulerWait.Start();	//Re-enter the active scheduler--execution halts here until RunL is called
+	
+	// after iActiveSchedulerWait has been stopped execution continues here
+	
+	return iIndex; // return the possible index of caller's number
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::SearchL
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::SearchL()
+    {
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::SearchL") );
+#endif
+  	// Try checking number of open stores to see if anything was opened
+    if ( iNumberOfOpenStores > 0 )
+        {
+        iOperation = iContactManager->MatchPhoneNumberL(
+            iNumberList->MdcaPoint( iNumberToMatch ), iDigitsToMatch, *this );
+    
+        // We must set ourselves to pending because we don't give our status to anybody
+        // When search is complete, the functions call our callbacks, and we complete ourselves
+        iStatus = KRequestPending;
+	    SetActive();
+        }
+    // If we do not become active, RunL stops ActiveSchedulerWait
+    }
+    
+// ---------------------------------------------------------
+// CMmsOwnNumber::CheckDuplicatesL
+// ---------------------------------------------------------
+//
+void CMmsOwnNumber::CheckDuplicatesL()
+    {
+    // If more than one contact found or length of number is less than the 
+    // match number length, check for exact match
+    
+    // The match array is in iResultArray
+    
+#ifdef _DEBUG
+    TMmsGenUtils::Log( _L("OwnNumber::CheckDuplicatesL") );
+#endif
+    delete iContact;
+    iContact = NULL;
+    
+    TInt count = 0;
+    if ( iResultArray )
+        {
+        count = iResultArray->Count();
+        }
+    
+    if (  iContactToMatch < count )
+        {
+        iMatch = EFalse;
+        iState = EMmsOwnNumberSearching;
+        iOperation = iContactManager->RetrieveContactL(
+                iResultArray->At( iContactToMatch ),
+                *this);
+        iStatus = KRequestPending;
+        SetActive();
+        }
+    else
+        {
+        delete iResultArray;
+        iResultArray = NULL;
+        iStatus = KRequestPending;
+        SetActive();
+ 	    TRequestStatus* s=&iStatus;
+        User::RequestComplete( s, KErrNone );
+        }
+    
+    }
+    
+    
+    
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File