diff -r 6a20128ce557 -r ebfee66fde93 mmsengine/mmsmessage/src/mmsownnumber.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsengine/mmsmessage/src/mmsownnumber.cpp Fri Jun 04 10:25:39 2010 +0100 @@ -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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ============================ 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... + // Analyze 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