diff -r 000000000000 -r 094583676ce7 wvuing/IMPSConnectionUI/ClientPluginSrc/CCnUiClientPluginIM.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/IMPSConnectionUI/ClientPluginSrc/CCnUiClientPluginIM.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,1180 @@ +/* +* Copyright (c) 2004 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: IM client plug-in. +* +*/ + +// INCLUDE FILES +#include "CCnUiClientPluginIM.h" +#include "CIMPSSharedDataFactory.h" +#include "IMPSSharedDataDefs.h" +#include "IMPSUIDDefs.h" +#include "impscommonuibuilddefinitions.h" + +//PEC attributes +#include +#include +#include +#include +#include + +//PEC attribute lists +#include +#include +#include + +//PEC contact lists +#include +#include +#include +#include + +// built-in resource reader +#include "CnUiResourceFileName.h" + +#include "PAppVariationNG.hrh" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "VariantKeys.h" +#include +#include "CIMPSSharedDataFactory.h" +#include "MIMPSSharedData.h" + + +// CONSTANTS + +_LIT( KPanicAttribute, "IMPSCommonUi Attribute" ); + +enum TIMAuthValues + { + EIMAuthValueAll = 0, + EIMAuthValueFriends, + EIMAuthValueNobody + }; + +// Authorize IM presence +_LIT( KIMPresenceAuth, "IMAuthIMPr" ); +// Table of userId specific Aliases +_LIT( KIMOwnAlias, "IMOwnAlias" ); + +// Separators for Alias table, to separate items from each other +// e.g [userid][itemsep][alias][tablesep][userid][itemsep][alias] etc... +// +const TUint KAliasItemSeparator = 0x10; +const TUint KAliasTableSeparator = 0x11; +const TInt KSeparatorSize = 2; // bytes + +// ================= MEMBER FUNCTIONS ======================= +// Two-phased constructor. +CCnUiClientPluginIM* CCnUiClientPluginIM::NewL( CPEngNWSessionSlotID2& aNWSessionSlotID ) + { + CCnUiClientPluginIM* self = new ( ELeave ) CCnUiClientPluginIM(); + + CleanupStack::PushL( self ); + self->ConstructL( aNWSessionSlotID ); + CleanupStack::Pop( self ); //self + + return self; + } + + +// Destructor +CCnUiClientPluginIM::~CCnUiClientPluginIM() + { + delete iSharedData; + iRFs.Close(); + delete iAlias; + } + + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CCnUiClientPluginIM::CCnUiClientPluginIM() + : CCnUiClientPluginBase( EIMPSConnClientIM ) + { + } + + +// Symbian OS default constructor can leave. +void CCnUiClientPluginIM::ConstructL( CPEngNWSessionSlotID2& aNWSessionSlotID ) + { + CCnUiClientPluginBase::ConstructL( aNWSessionSlotID ); + iSharedData = CIMPSSharedDataFactory::CreateTemporaryKeyHandlerL( NULL, KBrandingUid ); + + iRAUsed = 1 == ReadResourceIntValueL( RSC_CHAT_VARIATION_IMPSCU_REACTIVE_AUTHORIZATION ); + iAliasUsed = 1 == ReadResourceIntValueL( RSC_CHAT_VARIATION_USE_ALIAS_ATTRIBUTE ); + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::CurrentConnectionModeSettingL() +// From MCnUiClientPlugin +// ----------------------------------------------------------------------------- +// +TCnUiConnectionMode CCnUiClientPluginIM::CurrentConnectionModeSettingL() + { + MIMPSSharedData* sharedData = CIMPSSharedDataFactory::CreatePermanentKeyHandlerL( + NULL, + KIMPSServSettUid ); + TInt loginTypeSetting( EWVSettingsChatLoginManual ); + + // ignore return value since loginTypeSettings is unchanged from default if error occurs + sharedData->GetIntKey( EIMPSSharedKeysIMLogin, loginTypeSetting ); + + delete sharedData; + + TCnUiConnectionMode cMode( ECnUiCMAutomatic ); + if ( ( loginTypeSetting == EWVSettingsChatLoginManual ) || + ( loginTypeSetting == EWVSettingsChatLoginApplicationLaunch ) ) + { + cMode = ECnUiCMManual; + } + + return cMode; + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::ReWakeAutomaticConnectionModeL() +// From MCnUiClientPlugin +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::ReWakeAutomaticConnectionModeL() + { + MIMPSSharedData* sharedData = CIMPSSharedDataFactory::CreatePermanentKeyHandlerL( + NULL, + KIMPSServSettUid ); + + TInt loginTypeSetting( EWVSettingsChatLoginManual ); + + // ignore return value since loginTypeSettings is unchanged from default if error occurs + sharedData->GetIntKey( EIMPSSharedKeysIMLogin, loginTypeSetting ); + delete sharedData; + + + if ( ( loginTypeSetting == EWVSettingsChatLoginAutoAlways ) || + ( loginTypeSetting == EWVSettingsChatLoginAutoInHomeNW ) ) + { + //current mode setting is automatic + //==> re-wake with same mode + MIMPSSharedData* loginTypeNotifier = CIMPSSharedDataFactory::CreateTemporaryKeyHandlerL( + NULL, + KIMPSServSettNotifyUid ); + // just set the key + TInt err = loginTypeNotifier->SetIntKey( EIMPSSharedKeysServSettLoginTypeChangedIM, 0 ); + delete loginTypeNotifier; + if ( err ) + { + User::Leave( err ); + } + } + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::ConnectionOpenInitL() +// From MCnUiClientPlugin - connection open related methods +// Overloaded from CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::ConnectionOpenInitL( TBool aSapConnectionOpen, + const CIMPSSAPSettings& aSap ) + { + //let first the base class to do its things like disable synchronization + //of unknown lists + CCnUiClientPluginBase::ConnectionOpenInitL( aSapConnectionOpen, aSap ); + + // Get presence authorization level value + iPresenceAuth = 0; // use 0 as default value + aSap.GetOpaqueInt( KIMPresenceAuth, iPresenceAuth ); + + // Get and cache alias + TPtrC aliasPtr( KNullDesC ); + if ( aSap.GetOpaqueDesC16( KIMOwnAlias, aliasPtr ) == KErrNone ) + { + HBufC* userId = GetSharedDataL( EIMPSSharedKeysIMUserId ); + CleanupStack::PushL( userId ); + if ( userId->Length() != 0 ) + { + TInt index = KErrNotFound; + TInt length = 0; + LocateAliasL( aliasPtr, *userId, index, length ); + if ( index != KErrNotFound ) + { + // found correct alias + iAlias = aliasPtr.Mid( index, length ).AllocL(); + } + } + CleanupStack::PopAndDestroy( userId ); + } + + // default value + if ( !iAlias ) + { + iAlias = KNullDesC().AllocL(); + } + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DoVerifySapCapabilities() +// From CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +TBool CCnUiClientPluginIM::DoVerifySapCapabilities( TPEngWVCspServicesTree2 aCurrentNwServices ) + { + // For IM + Presence use WV server must support all of + // PEC engine needed main features + IM Specific ones... + // Logical and is used + //==> if any of these is EFalse, result will be EFalse + + TBool capabOK = ETrue; + + capabOK = aCurrentNwServices.iPresenceFeat.FeatureSupported(); + capabOK &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncGCLI ); + capabOK &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncMCLS ); + + capabOK &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncGETPR ); + capabOK &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncUPDPR ); + capabOK &= aCurrentNwServices.iPresenceFeat.FunctionSupported( KPEngWVPresDelivFunction ); + + + // IM feature capability check + capabOK &= aCurrentNwServices.iIMFeat.FeatureSupported(); + capabOK &= aCurrentNwServices.iIMFeat.SubFunctionSupported( KPEngIMSubFuncNEWM ); + + iAttribListsSupported = aCurrentNwServices.iPresenceFeat.FeatureSupported(); + iAttribListsSupported &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncCALI ); + iAttribListsSupported &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncDALI ); + iAttribListsSupported &= aCurrentNwServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncGALS ); + + return capabOK; + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DoClientKnownCntListsLC() +// Template method from CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +CDesCArray* CCnUiClientPluginIM::DoClientKnownCntListsLC() + { + //no way to know the number of lists so putting 1 as granularity + CDesCArrayFlat* lists = new ( ELeave ) CDesCArrayFlat( 1 ); + CleanupStack::PushL( lists ); + + CPEngContactListStore2* contactListStore = + CPEngContactListStore2::NewLC( *iNWSessionSlotID ); + + // get all contact lists + const MDesCArray& array = contactListStore->AllContactListsL(); + + for ( TInt i = 0; i < array.MdcaCount(); i++ ) + { + TPtrC list = array.MdcaPoint( i ); + + // now adding all list, except watcher list + // (also other old PEC UI -lists) + if ( 0 != list.CompareF( KPEngWatcherList ) ) + { + // this seems to be IM's list + lists->AppendL( list ); + } + } + CleanupStack::PopAndDestroy( contactListStore ); + + return lists; + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DoStartExplicitPostLoginSyncL() +// From CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::DoStartExplicitPostLoginSyncL() + { + // first do the base synchronization + if ( CurrentConnectionModeSettingL() == ECnUiCMAutomatic ) + { + // When AO is active we need to basesync lists so that we can + // update our attribute lists. + User::LeaveIfError( iPEngCntListPublisher->BaseSynchronizeContactLists( *this ) ); + SetStepProcessingActive(); + iStepId = ECntListPublish; + } + else // Manual login mode + { + // we can directly publish our attributes. + iStepId = EAttribListPublish; + IssueIMAttributeUpdateAndPublishIfNeededL( iPresenceAuth ); + } + } + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DoHandleExplicitPostLoginSyncStepCompleteL() +// From CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::DoHandleExplicitPostLoginSyncStepCompleteL( TStepId aStepId, + TInt& aStepStatus ) + { + + if ( aStepId == EBaseCntListSynch ) + { + // We end up here only if AO and BG handling are both active. + // We don't want to synchronize lists here so we skip that step. + aStepId = ECntListPublish; + } + + if ( ( aStepId == ECntListPublish ) && !iAttribListsSupported ) + { + // if attribute lists are not suppored we can skip the next + // step so we put EAttribListPublish as stepid + aStepId = EAttribListPublish; + } + + switch ( aStepId ) + { + case EBaseCntListSynch: + { + if ( aStepStatus == KErrNone ) + { + //doing explicit synchronization + MDesCArray* knownLists = DoClientKnownCntListsLC(); + + //and synchronize known IM lists explicitly with network server + //If list synchronization is actually done, then also attribute + //lists & attributes are synchronized. However, in some cases + //list synchronization isn't done and in those cases IM attributes + //must be pushed explicitly + + User::LeaveIfError( iPEngCntListPublisher->SynchronizeContactLists( + *knownLists, + *this ) ); + CleanupStack::PopAndDestroy(); //knownLists + SetStepProcessingActive(); + iStepId = ECntListPublish; + } + break; + } + + case ECntListPublish: + { + //initialize the local attribute lists & attributes as needed + MDesCArray* knownLists = DoClientKnownCntListsLC(); + + if ( iRAUsed ) + { + // reactive authorization, + // delete all the attribute lists + // including default attribute list + SetAuthorizationToNoneL( *knownLists ); + //initialize the local attribute lists & attributes as needed + iPEngAttributeListStore->DeleteDefaultAttributeListL(); + User::LeaveIfError( iPEngAttributeListPublisher->PublishAttributeLists( *this ) ); + SetStepProcessingActive(); + iStepId = EAttribListPublish; + } + else if ( ( aStepStatus == KErrNone ) || + ( aStepStatus == KPEngNwErrPartiallySuccessful ) ) + { + UpdateIMAttributeListsL( iPresenceAuth, *knownLists ); + + //Contact lists are now successfully synchronized + aStepStatus = KErrNone; + + User::LeaveIfError( iPEngAttributeListPublisher->PublishAttributeLists( *this ) ); + SetStepProcessingActive(); + iStepId = EAttribListPublish; + } + + CleanupStack::PopAndDestroy(); //knownLists + break; + } + + case EAttribListPublish: + { + if ( ( aStepStatus == KErrNone ) || + ( aStepStatus == KPEngNwErrPartiallySuccessful ) ) + { + //Attribute lists are now successfully synchronized + aStepStatus = KErrNone; + IssueIMAttributeUpdateAndPublishIfNeededL( iPresenceAuth ); + } + + break; + } + + case EAttributePublish: + { + //ignore possibly from attribute publish propagating errors + aStepStatus = KErrNone; + break; + } + + default: + { + //nothing to do + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DoStartPreLogoutPublishL() +// From CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::DoStartPreLogoutPublishL() + { + // nothing to do here as server takes care of OnlineStatus updating + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DoHandlePreLogoutPublishStepCompleteL() +// From CCnUiClientPluginBase +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::DoHandlePreLogoutPublishStepCompleteL( TStepId /*aStepId*/, + TInt& aStepStatus ) + { + //only attribute publish step is issued + //ignore errors coming from it + aStepStatus = KErrNone; + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::IMAttributePublishLevelL() +// Private helper +// ----------------------------------------------------------------------------- +// +TInt CCnUiClientPluginIM::IMAttributePublishLevelL() + { + + MIMPSSharedData* sharedData = CIMPSSharedDataFactory::CreatePermanentKeyHandlerL( + NULL, + KIMPSChatClientKeyUid ); + + TInt value( 0 ); + TInt err = sharedData->GetIntKey( EIMPSSharedKeysIMPresenceAuthSettingKey, value ); + + if ( err == KErrNotFound ) + { + // we can ignore not finding the key, since then the correct value is 0 + err = KErrNone; + } + + delete sharedData; + + // leave on other errors + User::LeaveIfError( err ); + + return value; + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::UpdateIMAttributeListsL() +// Private helper +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::UpdateIMAttributeListsL( TInt aPublishLevel, MDesCArray& aContactLists ) + { + if ( aPublishLevel == EIMAuthValueAll ) + { + SetAuthorizationToAllL( aContactLists ); + } + else if ( aPublishLevel == EIMAuthValueFriends ) + { + SetAuthorizationToFriendsL( aContactLists ); + } + else + { + SetAuthorizationToNoneL( aContactLists ); + } + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DefaultAttributeListLC() +// Private helper +// ----------------------------------------------------------------------------- +// +MPEngAttributeList2* CCnUiClientPluginIM::DefaultAttributeListLC( + CPEngAttributeListStore2& aAttributeListFactory ) + { + MPEngAttributeList2* list = NULL; + + //Loading error can be safely ígnored. + //If network list isn't available / can't be constructed + //(reported with leave) ==> blank list needs to be generated + TInt safelyIgnored; + TRAP( safelyIgnored, list = aAttributeListFactory.GetDefaultAttributeListL( + EPEngNetworkAttributeLists ) ); + + if ( !list ) // If network list is not available, then create it. + { + list = aAttributeListFactory.CreateEmptyAttributeListL(); + } + + CleanupClosePushL( *list ); + return list; + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::ReadIMAttributesL() +// Private helper +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::ReadIMAttributesL( + RPointerArray& aLockedOwnAttributes ) + { + RResourceFile resFile; + OpenResourceFileLC( resFile ); // Two items in cleanupstack. + + // read the data to a buffer + TInt plainResourceId = 0x00000fff & // Remove offset from id + RSC_CHAT_VARIATION_IMPSCU_LOGIN_ATTRIBUTES; + HBufC8* rawDataBuf = resFile.AllocReadLC( plainResourceId ); + + // and create resource reader for it + TResourceReader reader; + reader.SetBuffer( rawDataBuf ); + + // read attributes + TInt attributeCount( reader.ReadInt16() ); + for ( TInt i( 0 ); i < attributeCount; ++i ) + { + TInt attribute( reader.ReadInt16() ); + TInt qualifier( reader.ReadInt16() ); + TInt value( reader.ReadInt16() ); + TBool valueUsed( ETrue ); + + MPEngPresenceAttrModel2* attr = NULL; + TUint32 presenceAttr( 0 ); + TInt attrData( 0 ); + TInt attrField( 0 ); + TInt attrGroup( KPEngDefaultAttrValueGroup ); + + switch ( attribute ) + { + case EIMOnlineAttr: + { + presenceAttr = KUidPrAttrOnlineStatus; + switch ( value ) + { + case EIMOnlineNoChange: + { + valueUsed = EFalse; + break; + } + default: + { + User::Panic( KPanicAttribute, KErrArgument ); + } + } + break; + } + case EIMUserAvailabilityAttr: + { + presenceAttr = KUidPrAttrUserAvailability; + attrField = EPEngUsrAvailability; + switch ( value ) + { + case EIMUserAvailabilityNoChange: + { + valueUsed = EFalse; + break; + } + case EIMUserAvailabilityNotAvailable: + { + attrData = EPEngUsrAvailabilityOffline; + break; + } + case EIMUserAvailabilityDiscreet: + { + attrData = EPEngUsrAvailabilityDiscreet; + break; + } + case EIMUserAvailabilityAvailable: + { + attrData = EPEngUsrAvailabilityOnline; + break; + } + default: + { + User::Panic( KPanicAttribute, KErrArgument ); + } + } + break; + } + case EIMCommCapAttr: + { + presenceAttr = KUidPrAttrCommCap; + attrField = EPEngCommCapStatus; + attrGroup = EPEngCommCapIMClient; + switch ( value ) + { + case EIMCommCapNoChange: + { + valueUsed = EFalse; + break; + } + case EIMCommCapClosed: + { + attrData = EPEngCommCapStatusClosed; + break; + } + case EIMCommCapOpen: + { + attrData = EPEngCommCapStatusOpen; + break; + } + default: + { + User::Panic( KPanicAttribute, KErrArgument ); + } + } + break; + } + case EIMClientTypeAttr: + { + presenceAttr = KUidPrAttrClientInfo; + attrField = EPEngCliInfDeviceType ; + valueUsed = EFalse; + break; + } + default: + { + User::Panic( KPanicAttribute, KErrArgument ); + } + } + + TInt err( iPEngAttributeStore->GetAndLockOwnAttribute( presenceAttr, attr ) ); + if ( err == KErrNone ) + { + CleanupClosePushL( *attr ); + // set value + if ( valueUsed ) + { + attr->SetDataIntL( attrData, attrField, attrGroup ); + } + + // set qualifier + attr->SetQualifier( qualifier == EIMQualifierTrue ); + + aLockedOwnAttributes.AppendL( attr ); + CleanupStack::Pop(); // attr + } + else if ( err != KErrLocked ) + { + // if the model was locked, we want to continue with the other attributes + User::Leave( err ); + } + } + + CleanupStack::PopAndDestroy( 2 ); // rawDataBuf, resFile + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::IssueIMAttributeUpdateAndPublishIfNeededL() +// Private helper +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::IssueIMAttributeUpdateAndPublishIfNeededL( TInt aPublishLevel ) + { + if ( ( aPublishLevel != EIMAuthValueNobody ) || iRAUsed ) + { + RPointerArray models; + CleanupStack::PushL( TCleanupItem( DestroyCloseModelArray, &models ) ); + + // read own attributes to be published from resource + ReadIMAttributesL( models ); + + // Set the statustext + MPEngPresenceAttrModel2* statusText = NULL; + TInt err( iPEngAttributeStore->GetAndLockOwnAttribute( KUidPrAttrStatusText, + statusText ) ); + if ( err == KErrNone ) + { + CleanupClosePushL( *statusText ); + statusText->SetQualifier( ETrue ); + HBufC* statusMessage = GetFirstStatusMessageL(); + CleanupStack::PushL( statusMessage ); + statusText->SetDataDesC16L( *statusMessage, EPEngStatusText ); + CleanupStack::PopAndDestroy( statusMessage ); + models.AppendL( statusText ); + CleanupStack::Pop(); // statusText + } + else if ( err != KErrLocked ) + { + // if the model was locked, we want to continue with the other attributes + User::Leave( err ); + } + + if ( iAliasUsed ) + { + MPEngPresenceAttrModel2* alias = NULL; + err = iPEngAttributeStore->GetAndLockOwnAttribute( KUidPrAttrAlias, + alias ); + if ( err == KErrNone ) + { + CleanupClosePushL( *alias ); + alias->SetQualifier( ETrue ); + if ( iAlias->Length() == 0 ) + { + CleanupStack::PopAndDestroy(); // alias + } + else + { + alias->SetDataDesC16L( *iAlias, EPEngStatusText ); + models.AppendL( alias ); + CleanupStack::Pop(); // alias + } + } + else if ( err != KErrLocked ) + { + // if the model was locked, we want to continue with the other attributes + User::Leave( err ); + } + } + + // publish and unlock + User::LeaveIfError( iPEngAttributePublisher->PublishAndUnLockOwnAttributes( + models, *this ) ); + CleanupStack::Pop(); // models + + SetStepProcessingActive(); + iStepId = EAttributePublish; + } + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::LoginCancelledL() +// +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::LoginCancelledL() + { + MPEngPresenceAttrModel2* commCap = NULL; + TInt err = iPEngAttributeStore->GetAndLockOwnAttribute( KUidPrAttrCommCap, commCap ); + if ( err ) + { + // we can just return, since if we can't edit commcap, there's nothing + // we can do about it + return; + } + CleanupClosePushL( *commCap ); + commCap->SetDataIntL( EPEngCommCapStatusClosed, EPEngCommCapStatus, EPEngCommCapIMClient ); + commCap->SetQualifier( ETrue ); + iPEngAttributeStore->StoreOwnAttribute( *commCap ); + CleanupStack::PopAndDestroy(); // commCap + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::OpenResourceFileLC() +// !!!Notice!!!. Two variables in cleanupstack after call of this method. +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::OpenResourceFileLC( RResourceFile& aResourceFile ) + { + TFileName resourceFileName; + iRFs.Close(); + User::LeaveIfError( iRFs.Connect() ); + CnUiResourceFileName::NearestForCurrentLanguage( iRFs, resourceFileName ); + aResourceFile.OpenL( iRFs, resourceFileName ); + CleanupClosePushL( aResourceFile ); + aResourceFile.ConfirmSignatureL(); + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::OpenVariationResourceFileLC() +// !!!Notice!!!. Two variables in cleanupstack after call of this method. +// ----------------------------------------------------------------------------- +// + +//Ease of IM Branding +void CCnUiClientPluginIM::OpenVariationResourceFileLC( RResourceFile& aResourceFile ) + { + TFileName resourceFileName; + iRFs.Close(); + User::LeaveIfError( iRFs.Connect() ); + + TInt err = iSharedData->GetStringKey( ( TIMPSSharedKeys )KBrandingResourceKey, resourceFileName ); + if ( err || !resourceFileName.Length() ) + { + CnUiResourceFileName::NearestVariationForCurrentLanguage( iRFs, resourceFileName ); + } + aResourceFile.OpenL( iRFs, resourceFileName ); + CleanupClosePushL( aResourceFile ); + aResourceFile.ConfirmSignatureL(); + } + + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::ReadResourceIntValueL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiClientPluginIM::ReadResourceIntValueL( TInt aResourceId ) + { + + TInt val( 0 ); + TInt err ( KErrNone ); + + CRepository* rep = 0; + + TRAP( err, rep = CRepository::NewL( KCRUidIMNG ) ); + + if ( err == KErrNone ) + { + TInt key = aResourceId + KIMCUStartVariationID; + + err = rep->Get( key, val ); + + delete rep; + } + + if ( err != KErrNone ) + { + + RResourceFile resFile; + OpenVariationResourceFileLC( resFile ); // Two items in cleanup stack. + + aResourceId = aResourceId + RSC_CRRSS_CHAT_VARIATION_IMPSCU_START_ID; + + // read the data to a buffer + TInt plainResourceId = 0x00000fff & aResourceId; // Remove offset from id + HBufC8* rawDataBuf = resFile.AllocReadLC( plainResourceId ); + + // it's now as ascii code: \x00 for 0, \x01 for 1, etc. + TUint value = ( *rawDataBuf )[ 0 ]; + + CleanupStack::PopAndDestroy( 2 ); // rawDataBuf, resFile + + val = value; + } + + return val; + + } + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DestroyCloseModelArray() +// +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::DestroyCloseModelArray( TAny* aObject ) + { + reinterpret_cast*>( aObject )->ResetAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::SetAuthorizationToAllL +// Sets presence authorization mode to all +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::SetAuthorizationToAllL( MDesCArray& aContactLists ) + { + // Add CommCap/IM and OnlineStatus to default attribute list + MPEngAttributeList2* attrList = DefaultAttributeListLC( *iPEngAttributeListStore ); + attrList->AddPresenceAttributeL( KUidPrAttrCommCap ); + attrList->AddPresenceAttributeL( KUidPrAttrOnlineStatus ); + attrList->AddPresenceAttributeL( KUidPrAttrUserAvailability ); + attrList->AddPresenceAttributeL( KUidPrAttrStatusText ); + + if ( iAliasUsed ) + { + attrList->AddPresenceAttributeL( KUidPrAttrAlias ); + } + + iPEngAttributeListStore->SetAsDefaultAttributeListL( *attrList ); + CleanupStack::PopAndDestroy( attrList ); + + // remove possible authorizations from all contact lists + + // Deattach attribute-lists from all our contact-lists + DetachAttributeListL( aContactLists ); + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::SetAuthorizationToNoneL +// Sets presence authorization mode to none +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::SetAuthorizationToNoneL( MDesCArray& aContactLists ) + { + + // Remove CommCap/IM from default attribute list + MPEngAttributeList2* attrList = DefaultAttributeListLC( *iPEngAttributeListStore ); + attrList->RemoveAllAttributes(); + iPEngAttributeListStore->SetAsDefaultAttributeListL( *attrList ); + CleanupStack::PopAndDestroy( attrList ); + + // remove possible authorizations from all contact lists + + // Deattach attribute-lists from all our contact-lists + DetachAttributeListL( aContactLists ); + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::SetAuthorizationToFriendsL +// Sets presence authorization mode to friends +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::SetAuthorizationToFriendsL( + MDesCArray& aContactLists ) + { + // Remove CommCap/IM from default attribute list + MPEngAttributeList2* defaultAttrList = + DefaultAttributeListLC( *iPEngAttributeListStore ); + defaultAttrList->RemoveAllAttributes(); + iPEngAttributeListStore->SetAsDefaultAttributeListL( *defaultAttrList ); + CleanupStack::PopAndDestroy( defaultAttrList ); + + // Create attribute-list with CommCap-attribute + MPEngAttributeList2* attrList = + iPEngAttributeListStore->CreateEmptyAttributeListL(); + CleanupClosePushL( *attrList ); + attrList->AddPresenceAttributeL( KUidPrAttrCommCap ); + attrList->AddPresenceAttributeL( KUidPrAttrOnlineStatus ); + attrList->AddPresenceAttributeL( KUidPrAttrUserAvailability ); + attrList->AddPresenceAttributeL( KUidPrAttrStatusText ); + + if ( iAliasUsed ) + { + attrList->AddPresenceAttributeL( KUidPrAttrAlias ); + } + + // Attach created attribute-list to all contact-lists we have + AttachAttributeListL( aContactLists, *attrList ); + + CleanupStack::PopAndDestroy( attrList ); // attrList + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::AttachAttributeListL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::AttachAttributeListL( MDesCArray& aContactLists, + MPEngAttributeList2& aAttributeList ) + { + TInt count( aContactLists.MdcaCount() ); + + for ( TInt i( 0 ); i < count; ++i ) + { + TPtrC listId( aContactLists.MdcaPoint( i ) ); + + // Attach created attribute-list to our given contact-list + iPEngAttributeListStore-> + AttachAttributeListToContactListL( listId, aAttributeList ); + } + } + + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::DetachAttributeListL +// Cancels pending requests to network side. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCnUiClientPluginIM::DetachAttributeListL( MDesCArray& aContactLists ) + { + TInt count( aContactLists.MdcaCount() ); + + for ( TInt i( 0 ); i < count; ++i ) + { + TPtrC listId( aContactLists.MdcaPoint( i ) ); + + iPEngAttributeListStore-> + DeleteAttributeListFromContactListL( listId ); + } + } + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::GetFirstStatusMessageL +// Get first status message for online status. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +HBufC* CCnUiClientPluginIM::GetFirstStatusMessageL() const + { + RBuf buffer; + HBufC* message = NULL; + buffer.CreateL( RProperty::KMaxPropertySize ); + CleanupClosePushL( buffer ); + + MIMPSSharedData* sharedData = CIMPSSharedDataFactory::CreatePermanentKeyHandlerL( + NULL, + KIMPSChatClientKeyUid ); + // We can ignore errors + sharedData->GetStringKey( EIMPSSharedKeysIMStatusMsgOnlineKey, buffer ); + delete sharedData; + + RBuf header; + CleanupClosePushL( header ); + TInt offset( 1 ); // First character is for header length. + TInt headerLength( 0 ); + TInt err( KErrNone ); + if ( buffer.Length() ) + { + TLex lexer( buffer.Left( 1 ) ); + err = lexer.Val( headerLength ); + } + if ( !err && headerLength ) + { + header.CreateL( headerLength ); + TPtrC ptr( buffer.Mid( offset ) ); + if ( ptr.Length() > headerLength ) + { + header.Copy( ptr.Left( headerLength ) ); + header.Trim(); + TLex lexer( header ); + offset += headerLength; + TInt messageLength( 0 ); + TInt err( lexer.Val( messageLength ) ); + if ( err == KErrNone ) + { + ptr.Set( buffer.Mid( offset ) ); + if ( ptr.Length() >= messageLength ) + { + // Code scanner warning neglected to put variable on cleanup stack (Id: 35) + // this method cannot leave after this line + message = ptr.Left( messageLength ).AllocL(); // CSI: 35 # See above + } + } + } + } + + CleanupStack::PopAndDestroy( 2 ); // header, buffer + if ( !message ) + { + message = KNullDesC().AllocL(); + } + return message; + } + +// ----------------------------------------------------------------------------- +// CCnUiClientPluginIM::GetAliasL +// Get first status message for online status. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +HBufC* CCnUiClientPluginIM::GetSharedDataL( TIMPSSharedKeys aKey ) const + { + RBuf buffer; + HBufC* message = NULL; + buffer.CreateL( RProperty::KMaxPropertySize ); + CleanupClosePushL( buffer ); + + MIMPSSharedData* sharedData = CIMPSSharedDataFactory::CreatePermanentKeyHandlerL( + NULL, + KIMPSChatClientKeyUid ); + // We can ignore errors + sharedData->GetStringKey( aKey, buffer ); + delete sharedData; + + // Code scanner warning neglected to put variable on cleanup stack (Id: 35) + // This method cannot leave after this line + message = buffer.AllocL(); // CSI: 35 # See above + CleanupStack::PopAndDestroy(); // buffer + + if ( !message ) + { + message = KNullDesC().AllocL(); + } + return message; + } + +// --------------------------------------------------------- +// CCASettingsManager::LocateAliasL() +// --------------------------------------------------------- +// +void CCnUiClientPluginIM::LocateAliasL( const TDesC& aAliasTable, + const TDesC& aUserId, + TInt& aIndex, + TInt& aLength ) + { + aIndex = KErrNotFound; + aLength = 0; + if ( aAliasTable.Length() == 0 || aUserId.Length() == 0 ) + { + // nothing to search! + return; + } + + HBufC* findPattern = HBufC::NewLC( aUserId.Length() + + KSeparatorSize ); + TPtr find( findPattern->Des() ); + find.Copy( aUserId ); + TInt len = find.Length(); + find.Append( TChar( KAliasItemSeparator ) ); + TInt len2 = find.Length(); + + aIndex = aAliasTable.Find( find ); + if ( aIndex == KErrNotFound ) + { + // not found + CleanupStack::PopAndDestroy( findPattern ); + return; + } + + // found it, get length + aIndex += find.Length(); + TPtrC rest( aAliasTable.Mid( aIndex ) ); + aLength = rest.Locate( TChar( KAliasTableSeparator ) ); + if ( aLength == KErrNotFound ) + { + // this was last item + aLength = rest.Length(); + } + CleanupStack::PopAndDestroy( findPattern ); + return; + } + +// End of File