diff -r 000000000000 -r 2f259fa3e83a uifw/AknGlobalUI/OldStyleNotif/Src/AknSoftNotificationPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AknGlobalUI/OldStyleNotif/Src/AknSoftNotificationPlugin.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,2653 @@ +/* +* 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: +* +*/ + +// INCLUDE FILES + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "AknSoftNotificationPlugin.h" +#include +#include // for Messaging centre constants +#include "AknNotifyPlugin.hrh" +#include +#include +#include +#include +#include +#include +#include "AknNotifierController.h" +#include +#include +#include +#include +#include +#include +#include "AknCapServerEntry.h" +#include "AknDynamicNotificationData.h" +#include "aknsoftnoteconsts.h" +#include "akndynamicsoftnoteeventmanager.h" + +// Messaging UIDs +// Traditional messaging UIDs. +#define KMessagingCentreMainViewUid TVwsViewId(TUid::Uid(0x100058C5),TUid::Uid(0x01)) +#define KMessagingCentreInboxView TVwsViewId(TUid::Uid(0x100058C5),TUid::Uid(0x02)) + +// Conversational messaging UIDs. +#define KConversationApplicationViewUid TVwsViewId(TUid::Uid(0x2002A540),TUid::Uid(0x01)) +const TInt KConversationListViewUid = 0x01 ; + +// Messaging central repository. Used to read default view settings. +const TUid KCRUidMessageSettings = {0x101F87EB}; +const TUint32 KMessagingAppDefaultViewCRKey = 0x0000001C; + +// Cbs topic list view Uid. This view is shown when there are several cbs messages +#define KCbsApplicationUidTopicListView TVwsViewId(TUid::Uid(0x101F4CD3),TUid::Uid(0x02)) +// Cbs message view Uid. This view is shown when there is only one new cbs message +#define KCbsApplicationUidMessageView TVwsViewId(TUid::Uid(0x101F4CD3),TUid::Uid(0x04)) + +// Voice messages are handleb by speed dial application. +#define KSpeeddialVmbxDialUidView TVwsViewId( TUid::Uid( 0x1000590A ),TUid::Uid( 0x02 ) ) + +// Logs application UID +#define KUidLogs TUid(TUid::Uid(0x101F4CD5)) +_LIT8(KLogsActivationMsg ,"missed"); + +_LIT8( KExternalLaunch, "outside" ); + +#define KUidGS TUid(TUid::Uid(0x100058EC)) +#define KSettListNetViewId TUid(TUid::Uid(0x102824A8)) // Implementation UID for GSNetworkPlugin in GS. +#define KSelectNetworkAppUidView TVwsViewId(KUidGS, KSettListNetViewId) + +#define KChatSpecificView TVwsViewId(TUid::Uid(0x101F4673),TUid::Uid(7)) +const TInt KGSCustomActivateNetView = 9000; + +const TInt KSoftNoteGranularity = 4; + +const TInt KNetworkInfoPriority = 2500; +const TInt KSelectNetworkPriority = 2400; +const TInt KUSSDPriority = 2300; +const TInt KVoiceMailPriority = 2200; +const TInt KVoiceMailOnLinePriority = 2100; +const TInt KCBSPriority = 2000; +const TInt KGroupedNotification = 1500; +const TInt KMissedCallsPriority = 1300; +const TInt KNewMessagesPriority = 1200; +const TInt KChatMessagePriority = 1150; +const TInt KNewEmailPriority = 1100; + +/// Lowest value for unique id. Id range: KMinimumUniqueId...KMaxTInt. +const TInt KMinimumUniqueId = 0x00ff; + +#define KDeliveryTextMaxLength 64 + +_LIT( KAknSNFilename, "c:\\private\\10207218\\softnote.dat" ); +/// File where to store unique identification counter. +_LIT( KAknDynamicIdFilename, "c:\\private\\10207218\\dynamic.dat" ); + +NONSHARABLE_CLASS(CCustomNotifParams) : public CBase + { +public: + ~CCustomNotifParams() + { + delete iParamData; + delete iDynamicData; + if ( iCoeResourceHandle ) + { + CCoeEnv::Static()->DeleteResourceFile(iCoeResourceHandle); + } + }; + + /** + * Internalize content of CCustomNotifParams from stream. + * @param aStream Source stream. + */ + void InternalizeL( RReadStream& aStream ); + /** + * Externalize content of CCustomNotifParams to stream. + * @param aStream Destination stream. + */ + void ExternalizeL( RWriteStream& aStream ) const; + /** + * Return text for custom notification. + * + * @param aCount Count of items to be displayed in notification. + * @param aGroupText ETrue : Text is shown in grouped list. + * EFalse : Text is shown in single dialog. + * @return Custom text. + */ + const TDesC& CustomText( TInt aCount, TBool aGroupText ) const; + /** + * @return View activation message or KNullDesC8 if not defined. + */ + const TDesC8& ViewActivationMessage() const; + /** + * @return Flag whether user events are wanted by the event manager. + */ + TBool EnableObserver() const; + + TInt iId; + TInt iNoteId; + TBool iSupportsGroupedform; + TBool iHasViewInfo; + TInt iCount; + /// Data for custom soft notification. + CAknPrivateSoftNoteParameters* iParamData; + /// Data for dynamic soft notification. + CAknDynamicNotificationData* iDynamicData; + /// Parameter type to distinguish dynamic note from custom note. + /// Use KAknSoftNotificationCustom or KAknSoftNotificationDynamic. + TInt iParamType; + CCustomNotifParams* iNext; + TInt iCoeResourceHandle; + }; + +TBool CCustomNotifParams::EnableObserver() const + { + if (iDynamicData) + { + return iDynamicData->EnableObserver(); + } + else + { + return EFalse; + } + } + +// --------------------------------------------------------- +// CCustomNotifParams::InternalizeL +// --------------------------------------------------------- +// +void CCustomNotifParams::InternalizeL( RReadStream& aStream ) + { + iParamType = aStream.ReadInt16L(); + switch( iParamType ) + { + case KAknSoftNotificationCustom: + { + CAknPrivateSoftNoteParameters* param = + CAknPrivateSoftNoteParameters::NewL(); + aStream >> *param; + delete iParamData; + iParamData = param; + break; + } + case KAknSoftNotificationDynamic: + { + CAknDynamicNotificationData* data = + CAknDynamicNotificationData::NewLC( aStream ); + + // Duplicate values to ease the changes required + // + CAknPrivateSoftNoteParameters* param = + CAknPrivateSoftNoteParameters::NewL(); + CleanupStack::PushL( param ); + + // copy some values + param->iCustomMessageId = data->CustomMsgUid(); + param->iPluralViewId = data->PluralViewId(); + param->iViewId = data->ViewId(); + param->iPriority = data->Priority(); + param->iTone = data->Tone(); + param->iNoteResourceId = data->Id(); + param->iAcceptSoftKey = EAknSoftkeyShow; + + // secondary display data + if( aStream.ReadInt8L() ) + { + // item has secondary display data + CAknSDData* sddata = new (ELeave) CAknSDData(); + CleanupStack::PushL( sddata ); + aStream >> *sddata; + delete param->iSecondaryDisplayData; + param->iSecondaryDisplayData = sddata; + CleanupStack::Pop( sddata ); + } + + // Assign values when we can't leave anymore. + CleanupStack::Pop( 2, data ); // param + delete iParamData; + iParamData = param; + delete iDynamicData; + iDynamicData = data; + + break; + } + default: + { + User::Leave( KErrCorrupt ); + break; + } + } + } + +// --------------------------------------------------------- +// CCustomNotifParams::ExternalizeL +// --------------------------------------------------------- +// +void CCustomNotifParams::ExternalizeL( RWriteStream& aStream ) const + { + if( iParamType <= KAknSoftNotificationCustom && iParamData ) // default + { + aStream.WriteInt16L( KAknSoftNotificationCustom ); + aStream << *iParamData; + } + else if( iParamType == KAknSoftNotificationDynamic && iDynamicData ) + { + aStream.WriteInt16L( KAknSoftNotificationDynamic ); + aStream << *iDynamicData; + + // secondary display data + if( iParamData && iParamData->iSecondaryDisplayData ) + { + aStream.WriteInt8L( ETrue ); + aStream << iParamData->iSecondaryDisplayData; + } + else + { + aStream.WriteInt8L( EFalse ); + } + } + else + { + User::Leave( KErrCorrupt ); + } + } + +// --------------------------------------------------------- +// CCustomNotifParams::CustomText +// --------------------------------------------------------- +// +const TDesC& CCustomNotifParams::CustomText( + TInt count, TBool aGroupText ) const + { + if( iParamType == KAknSoftNotificationDynamic && iDynamicData ) + { + if( count > 1 ) + { + // use plural text + return aGroupText ? iDynamicData->PluralLabelGroup() : + iDynamicData->PluralLabel(); + } + else + { + // use singular text + return aGroupText ? iDynamicData->SingularLabelGroup() : + iDynamicData->SingularLabel(); + } + } + return KNullDesC(); + } + +// --------------------------------------------------------- +// CCustomNotifParams::ViewActivationMessage +// --------------------------------------------------------- +// +const TDesC8& CCustomNotifParams::ViewActivationMessage() const + { + if( iParamType == KAknSoftNotificationDynamic && iDynamicData ) + { + return iDynamicData->CustomMsg(); + } + else if( iParamData && iParamData->iViewActivationMsg ) + { + return *iParamData->iViewActivationMsg; + } + return KNullDesC8(); + } + +void AknSoftNoteSDObserver::SetSoftNotificationSubject( CAknSoftNotificationSubject* aSubject ) + { + iSubject = aSubject; + } + +TAknDialogMediatorObserverCommand AknSoftNoteSDObserver::MediatorCommandL( TUid, TUid, TInt, + const TDesC8& aData) + { + RDesReadStream* readStreamSDData = new(ELeave) RDesReadStream(); + CleanupStack::PushL( readStreamSDData ); + readStreamSDData->Open( aData ); // aData = data received from Mediator + TPckgBuf paramsBuf; + *readStreamSDData >> paramsBuf; + + if ( paramsBuf().iType == EShowGroupedNotification ) + { + CAknGroupedNotifierNote* groupedNote = iSubject->iGroupedNote; + iSubject->GroupedNoteCompletedL(EAknSoftkeyExit, EMaxItem); // saves as well + // iSubject->iGroupedNote equals to NULL now + delete groupedNote; + } + + else if (paramsBuf().iType != ECustomSoftNotification ) + { + TAknSoftNotificationType type = paramsBuf().iType; + iSubject->iSoftNotificationAmounts[ type ] = 0; + iSubject->RemoveByType( type ); + + if ( type == EMissedCallsNotification || + type == ENewMessagesNotification || + type == ENewMailNotification || + type == EChatMessageNotification) + { + iSubject->RemoveByType(EShowGroupedNotification); + iSubject->ScheduleGroupedNotifierL(); + } + else + { + iSubject->iGlobalNoteController->TryDisplayNextNoteL(); + } + + iSubject->iNotificationsSaved = EFalse; + iSubject->SaveSoftNotificationsL(); + } + + else + { + CCustomNotifParams* params = iSubject->iCustomNoteParamsStack; + for (;params;params = params->iNext) + { + if (params->iParamData->iSecondaryDisplayData) + { + if ( params->iParamData->iSecondaryDisplayData->iCategory.iUid == paramsBuf().iCategory + && params->iParamData->iSecondaryDisplayData->iDialogIdx == paramsBuf().iDialogID ) + { + TInt noteId = params->iNoteId; + if ( noteId == 0 ) + { + iSubject->RemoveCustomNoteForId( params->iId ); + iSubject->ScheduleGroupedNotifierL(); + } + else + { + iSubject->RemoveCustomNoteForId( noteId, ETrue ); + if ( noteId != KErrNotFound ) // was added to global notes queue + { + iSubject->iGlobalNoteController->TryDisplayNextNoteL(); + } + } + + iSubject->iNotificationsSaved = EFalse; + iSubject->SaveSoftNotificationsL(); + break; + } + } + } + } + + readStreamSDData->Close(); + CleanupStack::PopAndDestroy(); // read stream + return EDoNothingWithThisCommand; + } + + +// ================= MEMBER FUNCTIONS ======================= + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CAknSoftNotificationSubject::CAknSoftNotificationSubject( + MAknKeyLockController* aKeyLockController, + CAknGlobalNoteSubject* aGlobalNoteController) +:iKeyLockController(aKeyLockController), + iGlobalNoteController(aGlobalNoteController), + iNotificationsSaved(ETrue), // We'll have to assume there are saved notifications on startup + iUniqueIdCounter(KMinimumUniqueId) + { + iMessagingRepository = NULL; + iDynamicSoftNoteManager = CAknDynamicSoftNoteEventManager::UniqueInstance(); + __ASSERT_ALWAYS(iDynamicSoftNoteManager != NULL, User::Invariant()); + } + +// EPOC default constructor can leave. +void CAknSoftNotificationSubject::ConstructL() + { + iKeyLockController->AddObserverL(this); + + iSoftNoteEntryList = new(ELeave)CArrayFixFlat(KSoftNoteGranularity); + iGlobalNoteController->SetSoftNoteObserver(this); + // Set initial state to 'non-idle' + iGlobalNoteController->SetMaxDisplayPriorityL(KMinimumSoftNotePriority); + + iGlobalNoteController->SetMessageNotifierObserver(this); + + // Messaging settings repository + TRAP_IGNORE( iMessagingRepository = CRepository::NewL(KCRUidMessageSettings) ); + +#ifdef __COVER_DISPLAY + // Just to give something, not used. + iCoverClient = CAknMediatorFacade::NewL((CEikDialog*)CEikonEnv::Static()->Alert()->AsEikDialog()); + + iCoverClient->SetObserver(&iObsStub); + iObsStub.SetSoftNotificationSubject( this ); + iCoverClient->CatUid() = KAknSecondaryDisplayCategory; + iCoverClient->DialogIndex() = EAknSoftNotificationSDInfo; +#endif + + // If the loading fails, then we'll start using unique id's + // from KMinimumUniqueId. + TRAPD( err, LoadUniqueIdL() ); + if( err ) + { +#ifdef _DEBUG + _LIT( KDmsg, "AknSoftNotificationPlugin, Unique Id restore err: %d" ); + RDebug::Print( KDmsg, err ); +#endif //_DEBUG + } + } + +CAknSoftNotificationSubject::~CAknSoftNotificationSubject() + { + delete iSoftNoteEntryList; + + while(iCustomNoteParamsStack) + { + CCustomNotifParams* params = iCustomNoteParamsStack->iNext; + delete iCustomNoteParamsStack; + iCustomNoteParamsStack = params; + } + + delete iIdle; + delete iCoverClient; + + if(iKeyLockController) + { + iKeyLockController->RemoveObserver(this); + } + + if ( iMessagingRepository ) + { + delete iMessagingRepository; + iMessagingRepository = NULL; + } + } + +// Two-phased constructor. +CAknSoftNotificationSubject* CAknSoftNotificationSubject::NewL( + MAknKeyLockController* aKeyLockController, + CAknGlobalNoteSubject* aGlobalNoteController ) + { + CAknSoftNotificationSubject* self = new (ELeave) CAknSoftNotificationSubject( + aKeyLockController, + aGlobalNoteController); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self); + return self; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::KeyLockStatusChange +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::KeyLockStatusChange(TKeyLockStatus aStatus) + { + if ( aStatus == EKeyLockEnabled ) + { + iKeysLocked = ETrue; + } + else if ( aStatus == EKeyLockDisabled ) + { + iKeysLocked = EFalse; + } + + if ( iGroupedNote && iGroupedNote->ListBox()) + { + if ( aStatus == EKeyLockEnabled ) + { + iGroupedNote->ListBox()->View()->ItemDrawer()->SetFlags( + CListItemDrawer::EDisableHighlight); + + iGroupedNote->DrawDeferred(); + } + else if ( aStatus == EKeyLockDisabled ) + { + iGroupedNote->ListBox()->View()->ItemDrawer()->ClearFlags( + CListItemDrawer::EDisableHighlight); + + iGroupedNote->DrawDeferred(); + } + } + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::Release() +// +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::Release() + { + delete this; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::RegisterL() +// (other items were commented in a header). +// --------------------------------------------------------- +// +CAknSoftNotificationSubject::TNotifierInfo CAknSoftNotificationSubject::RegisterL() + { + iInfo.iUid=KAknSoftNotificationUid; + iInfo.iChannel=EAknNotifierChannelNote; + iInfo.iPriority=ENotifierPriorityHigh; + return iInfo; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::Info() +// (other items were commented in a header). +// --------------------------------------------------------- +// +CAknSoftNotificationSubject::TNotifierInfo CAknSoftNotificationSubject::Info() const + { + return iInfo; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::StartL(const TDesC8& aBuffer) +// +// (other items were commented in a header). +// --------------------------------------------------------- +// +TPtrC8 CAknSoftNotificationSubject::StartL(const TDesC8& aBuffer) + { + TInt id = KErrNotFound; + HandleNotifierMessageL( aBuffer, id ); + + if( id > 0 ) + { + // Custom note id generated, report it back to client + WriteResponse( iResponseMsg, id ); + return iResponseMsg; + } + return KNullDesC8(); + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::StartL() +// This is the asynchronous version that should not be used +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::StartL(const TDesC8& aBuffer, TInt aReplySlot, + const RMessagePtr2& aMessage) + { + TInt id = KErrNotFound; + HandleNotifierMessageL( aBuffer, id ); + if( id > 0 ) + { + // Custom note id generated, report it back to client + WriteResponse( iResponseMsg, id ); + aMessage.WriteL( aReplySlot, iResponseMsg ); + } + aMessage.Complete( KErrNone ); + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::Cancel() +// Not much happening here. If a certain type of of soft +// notification should be canceled, please use the wrapper's +// method +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::Cancel() + { + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::UpdateL(const TDesC8& aBuffer) +// +// (other items were commented in a header). +// --------------------------------------------------------- +// +TPtrC8 CAknSoftNotificationSubject::UpdateL(const TDesC8& aBuffer) + { + return StartL( aBuffer ); + } + +// --------------------------------------------------------- +// HandleMessageL(const TDesC8& aBuffer) +// Required because of framework +// (other items were commented in a header). +// --------------------------------------------------------- +// +void HandleMessageL( const TDesC8& /*aBuffer*/ ) + { + } + +void CAknSoftNotificationSubject::HandleNotifierMessageL( + const TDesC8& aBuffer, TInt& aNoteId ) + { + RDesReadStream readStream( aBuffer ); + + if ( aBuffer.Length() < 4 // TInt takes four char + || readStream.ReadInt32L() != KAKNNOTIFIERSIGNATURE ) + { + User::Leave( KErrArgument ); + } + + TAknSoftNotificationType type = STATIC_CAST(TAknSoftNotificationType,readStream.ReadUint8L()); + TInt16 count = readStream.ReadInt16L(); + + //set current idle status to appui + if ( type == ESetIdleState ) + { + ((CAknCapAppServerAppUi*)(CEikonEnv::Static())->EikAppUi()) + ->SetIdleActive( count ? ETrue : EFalse ); + } + + switch ( type ) + { + case ENetworkInformationNotification: + case ESelectNetworkNotification: + case EUnstructuredSSDataNotification: + case EVoiceMailNotification: + case ESeparateVoiceMailOnLine1Notification: + case ESeparateVoiceMailOnLine2Notification: + case ECellBroadcastNotification: + case EDeliveryReportNotification: + case EClass0SmsNotification: + case EMissedCallsNotification: + case ENewMessagesNotification: + case ENewMailNotification: + case EShowActiveNotifications: + case EShowGroupedNotification: + case ECustomSoftNotification: + case EChatMessageNotification: + case ESetIdleState: + break; + case ENoSoftNotification: + case EMaxSoftNotification: + default: + // Simply return with no error code. + return; + } + + // Stores value for future use. + TBool notificationsSavedTmp = iNotificationsSaved; + + TInt err = KErrNone; + if ( !iIdleStateActive ) + { + TRAP( err, LoadAndQueueSoftNotesL() ); // leaves if file does not exist. + } + else if ( type != ESetIdleState && type != EShowActiveNotifications ) + { + // To make sure that changes will be saved even we didn't load them. + iNotificationsSaved = EFalse; + } + + if ( err && err != KErrNotFound && err != KErrNoMemory ) + { + // There was an error, check allowed error codes, others mean corruption of data. + CEikonEnv::Static()->FsSession().Delete( KAknSNFilename ); + iNotificationsSaved = EFalse; + } + +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin, HandleNotifierMessageL:type %d,count %d, Load returned %d"); + RDebug::Print(KDmsg,type,count,err); +#endif + + if ( type == EShowActiveNotifications ) + { + return; + } + + if ( type == ESetIdleState ) + { + if ( count ) + { + iGlobalNoteController->SetMaxDisplayPriorityL( KMaxTInt ); + iIdleStateActive = ETrue; + } + else + { + iGlobalNoteController->SetMaxDisplayPriorityL( KMinimumSoftNotePriority ); + iIdleStateActive = EFalse; + } + return; + } + + TChar isCancel = readStream.ReadUint8L(); + TChar addCount = readStream.ReadUint8L(); + + // using hbuf allows us to use dynamic sized buffers, client should send the info... + HBufC* noteTextH = HBufC::NewLC( KGlobalNoteTextLength ); + TPtr noteText = noteTextH->Des(); + + readStream >> noteText; + + if ( count == 0 && !addCount ) + { + isCancel = 1; // true + } + else if ( count < 0 ) + { + count = 1; + } + + if ( type == ECustomSoftNotification ) + { + TInt customNoteID = readStream.ReadInt32L(); + + CCustomNotifParams* params = SeekCustomNoteForId( customNoteID ); + TInt noteId = ( params==0 ) ? KErrNotFound : params->iNoteId; + + if ( isCancel ) + { + if ( !params ) + { + // No note for id, no need to do anything but restore the iNotificationsSaved value. + CleanupStack::PopAndDestroy( noteTextH ); + iNotificationsSaved = notificationsSavedTmp; + return; + } + + if ( noteId == 0 ) // was displayed in grouped form + { + RemoveCustomNoteForId( customNoteID ); + + if (!IsGroupedFormed()) + { + // ScheduleGroupedNotifierL does not remove EShowGroupedNotification item + // so let's do it here. + RemoveByType(EShowGroupedNotification); + } + + ScheduleGroupedNotifierL(); + SaveSoftNotificationsL(); + + // If grouped note was visible and only one groupable soft note was left, + // then iSoftNoteEntryList and iCustomNoteParamsStack states are not exactly + // correct. Load restores this state. + TRAP_IGNORE(LoadAndQueueSoftNotesL()); + } + else + { + RemoveCustomNoteForId( noteId, ETrue ); + if ( noteId != KErrNotFound ) // was added to global notes queue + { + iGlobalNoteController->TryDisplayNextNoteL(); + } + + SaveSoftNotificationsL(); + } + + CleanupStack::PopAndDestroy( noteTextH ); + return; + } + + if ( params ) // Remove old + { + count += ( addCount ? params->iCount : 0 ); + TBool isNotGrouped = noteId != 0; + RemoveCustomNoteForId( isNotGrouped ? noteId : customNoteID, isNotGrouped ); + } + + TBool newNote = ( params == NULL ); + AddNewCustomNoteL( readStream, count, newNote ); + + if( iCustomNoteParamsStack && + iCustomNoteParamsStack->iParamType == KAknSoftNotificationDynamic ) + { + aNoteId = iCustomNoteParamsStack->iId; // generated id + TPtrC customTxt( iCustomNoteParamsStack->CustomText( count, EFalse ) ); + if( customTxt.Length() > 0 ) + { + noteText.Copy( customTxt.Left( KGlobalNoteTextLength ) ); + } + } + } + + if ( !isCancel ) + { +#ifdef __COVER_DISPLAY + // Play tone for select network notification immediately if device has cover display. + if ((type == ESelectNetworkNotification) && count && !iSoftNotificationAmounts[type]) + { + ((CAknCapAppServerAppUi*)(CEikonEnv::Static())->EikAppUi())->KeySounds()-> + PlaySound(CAknNoteDialog::EErrorTone); + } +#endif // __COVER_DISPLAY + + TBool countChanged = ETrue; + + if ( addCount ) + { + iSoftNotificationAmounts[type] += count; + } + else + { + if ( iSoftNotificationAmounts[type] == count ) + { + // If the amount is not changed, set up a flag for + // not updating the note. + countChanged = EFalse; + } + iSoftNotificationAmounts[type] = count; + } + + UpdateNoteL(type, noteText, iSoftNotificationAmounts[type], countChanged); + CleanupStack::PopAndDestroy( noteTextH ); + + User::ResetInactivityTime(); + } + else // Cancel note by type + { + CleanupStack::PopAndDestroy( noteTextH ); + + if (iSoftNotificationAmounts[type] == 0) + { + // There is not this type of soft notifications on queue + // Just restore the iNotificationsSaved value and return. + iNotificationsSaved = notificationsSavedTmp; + return; + } + + iSoftNotificationAmounts[type] = 0; + RemoveByType(type); + + if (type == EMissedCallsNotification || + type == ENewMessagesNotification || + type == ENewMailNotification || + type == EChatMessageNotification) + { + RemoveByType(EShowGroupedNotification); + ScheduleGroupedNotifierL(); + } + else + { + iGlobalNoteController->TryDisplayNextNoteL(); + } + } + + SaveSoftNotificationsL(); + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::GroupedNoteCompletedL(TInt aCommandId,TAknGroupedNotifierItem aSelectedItem) +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::GroupedNoteCompletedL(TInt aCommandId,TAknGroupedNotifierItem aSelectedItem) + { + if ( iGroupedNote ) + { + //No delete is necessary as the dialog will take care of deleting itself + iGroupedNote->RemoveEditorIndicator(); + iGroupedNote = NULL; + } + + if ( aCommandId == EEikBidTab ) // Apps or end-key pressed + { + SaveSoftNotificationsL(); + ClearAllNotes(); + return; + } + + if ( aCommandId == EAknSoftkeyExit ) + { + SetNcnFlag(EFalse); + } + + // Make sure goruped notification is removed from queue + RemoveByType(EShowGroupedNotification); + + if (aSelectedItem > EMaxItem || aSelectedItem < 0 ) // out of "static" range + { + CCustomNotifParams* params = SeekCustomNoteForId(aSelectedItem); + if (params) + { + HandleCustomNoteCompletedL(params, aCommandId); + } + RemoveCustomNoteForId(aSelectedItem); + + // To allow this to fall through next clause (saving, rescheduling etc.). + aCommandId = EAknSoftkeyOk; + } + + if (aCommandId == EAknSoftkeyShow || aCommandId == EAknSoftkeyOk) + { + if (aSelectedItem == EMissedCalls) + { + iSoftNotificationAmounts[EMissedCallsNotification] = 0; + LaunchMissedCallsAppL(); + } + else if (aSelectedItem == ENewMessages) + { + iSoftNotificationAmounts[ENewMessagesNotification] = 0; + LaunchNewMessagesAppL(); + } + else if (aSelectedItem == ENewChatMsgs) + { + iSoftNotificationAmounts[EChatMessageNotification] = 0; + LaunchNewIMAppL(); + } + else if (aSelectedItem == ENewMails) + { + iSoftNotificationAmounts[ENewMailNotification] = 0; + LaunchNewMailAppL(); + } + + ScheduleGroupedNotifierL(); + iNotificationsSaved = EFalse; + + } + else if (aCommandId == EAknSoftkeyExit || aCommandId == KErrCancel) + { + if ( aCommandId == EAknSoftkeyExit ) + { + iSoftNotificationAmounts[EMissedCallsNotification] = 0; + iSoftNotificationAmounts[ENewMessagesNotification] = 0; + iSoftNotificationAmounts[EChatMessageNotification] = 0; + iSoftNotificationAmounts[ENewMailNotification] = 0; + + // Null Customs + CCustomNotifParams* params = iCustomNoteParamsStack; + while(params) + { + CCustomNotifParams* tmp = params->iNext; + if (params->iSupportsGroupedform) + { + if( params->iParamType == KAknSoftNotificationDynamic ) + { + if (params->EnableObserver()) + { + // notify user event + iDynamicSoftNoteManager->IssueEvent( + params->iId, EAknDynamicSNoteEventCanceled, ETrue); + } + } + RemoveCustomNoteForId(params->iId); + } + params = tmp; + } + + RemoveByType(EShowGroupedNotification); // Remove also from global notes queue + iNotificationsSaved = EFalse; + } + iGlobalNoteController->TryDisplayNextNoteL(); + } + SaveSoftNotificationsL(); + } + + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::UpdateNoteL(TSoftNotifierType aType) +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::UpdateNoteL( + TAknSoftNotificationType aType,const TDesC& aText, TInt aCount, TBool aCountChanged) + { + iLatestType = aType; + + if ((aType > ENoSoftNotification && aType < EMissedCallsNotification) + || aType == ECustomSoftNotification) + { + // Received an ungrouped soft notification + DisplayUngroupedNotifierL(aType, aText, aCount); + } + else if ((aType >= EMissedCallsNotification && aType <= ENewMailNotification) + || aType == EChatMessageNotification) + { + // Set shared data flag if this is missed calls notification. + // This is needed for synchronizing notes with screensaver + // indicator view. + if (aType == EMissedCallsNotification && aCount > 0) + { + SetNcnFlag( ETrue ); + } + + // Update grouped notifier only if the count has actually changed. + // This removes flicker in some cases. + if ( aCountChanged ) + { + ScheduleGroupedNotifierL(); + } + } + } + + +void CAknSoftNotificationSubject::ScheduleGroupedNotifierL() + { + // Possible grouped notification + TBool grouped = IsGroupedFormed(); + if (grouped) + { + if (iGroupedNote) + { + // grouped note already exists, so just update it + ShowGroupedNotificationL(); + } + else + { + // Schedule grouped note + RemoveByType(EShowGroupedNotification); + RemoveByType(EMissedCallsNotification); + RemoveByType(ENewMessagesNotification); + RemoveByType(EChatMessageNotification); + RemoveByType(ENewMailNotification); + + CCustomNotifParams* params = iCustomNoteParamsStack; + for (;params;params = params->iNext) + { + if( params->iSupportsGroupedform ) + { + if ( params->iNoteId != KErrNotFound && params->iNoteId != 0) + { + iGlobalNoteController->CancelNote(params->iNoteId, EFalse); + for (TInt ii = 0; ii < iSoftNoteEntryList->Count(); ii++) + { + if (params->iNoteId == iSoftNoteEntryList->At(ii).iId ) + { + iSoftNoteEntryList->At(ii).iId = 0; + iSoftNoteEntryList->At(ii).iCustomId = params->iId; + break; + } + } + } + + params->iNoteId = 0; + } + } + + // Create grouped notification + TSoftNoteEntry softNote; + softNote.iType = EShowGroupedNotification; + softNote.iId = iGlobalNoteController->AddSoftNotificationL(KNullDesC, 0, 0, + KGroupedNotification, 0); + iGlobalNoteController->TryDisplayNextNoteL(); + iSoftNoteEntryList->AppendL(softNote); + } + } + else + { + if (iGroupedNote) + { + delete iGroupedNote; + iGroupedNote = NULL; + } + // Display using ungrouped layout + if (iSoftNotificationAmounts[EMissedCallsNotification]) + { + DisplayUngroupedNotifierL(EMissedCallsNotification, KNullDesC, + iSoftNotificationAmounts[EMissedCallsNotification]); + } + if (iSoftNotificationAmounts[ENewMessagesNotification]) + { + DisplayUngroupedNotifierL(ENewMessagesNotification, KNullDesC, + iSoftNotificationAmounts[ENewMessagesNotification]); + } + if (iSoftNotificationAmounts[EChatMessageNotification]) + { + DisplayUngroupedNotifierL(EChatMessageNotification, KNullDesC, + iSoftNotificationAmounts[EChatMessageNotification]); + } + if (iSoftNotificationAmounts[ENewMailNotification]) + { + DisplayUngroupedNotifierL(ENewMailNotification, KNullDesC, + iSoftNotificationAmounts[ENewMailNotification]); + } + } + } + + + +void CAknSoftNotificationSubject::DisplayUngroupedNotifierL(TAknSoftNotificationType aType, + const TDesC& aText, TInt aCount) + { + TInt resource = 0; + TInt priority = 0; + TBool cancel = EFalse; + TInt count = 0; + TInt softkeys = 0; + TInt tone = 0; // ENoTone; + switch (aType) + { + case ENetworkInformationNotification: + resource = R_NETWORK_INFORMATION_NOTE; + softkeys = R_AVKON_SOFTKEYS_OK_EMPTY__OK; + priority = KNetworkInfoPriority; + break; + case ESelectNetworkNotification: + resource = R_SELECT_NETWORK_NOTE; + softkeys = R_AVKON_SOFTKEYS_OK_CANCEL__OK; + priority = KSelectNetworkPriority; +#ifndef __COVER_DISPLAY + tone = CAknNoteDialog::EErrorTone; +#endif // __COVER_DISPLAY + if ( CheckIfAlreadyExists(ESelectNetworkNotification) ) + { + return; + } + break; + case EUnstructuredSSDataNotification: + resource = R_UNSTRUCTURED_SS_DATA_NOTE; + softkeys = R_AVKON_SOFTKEYS_READ_EXIT__READ; + priority = KUSSDPriority; + break; + case EVoiceMailNotification: + resource = R_VOICE_MAIL_NOTE; + softkeys = R_AVKON_SOFTKEYS_LISTEN_EXIT__LISTEN; + priority = KVoiceMailPriority; + cancel = ETrue; + break; + case ESeparateVoiceMailOnLine2Notification: + resource = R_VOICE_MAIL_ON_LINE2_NOTE; + softkeys = R_AVKON_SOFTKEYS_LISTEN_EXIT__LISTEN; + priority = KVoiceMailOnLinePriority; + cancel = ETrue; + break; + case ESeparateVoiceMailOnLine1Notification: + resource = R_VOICE_MAIL_ON_LINE1_NOTE; + softkeys = R_AVKON_SOFTKEYS_LISTEN_EXIT__LISTEN; + priority = KVoiceMailOnLinePriority; + cancel = ETrue; + break; + case ECellBroadcastNotification: + resource = R_CELL_BROADCAST_NOTE; + softkeys = R_AVKON_SOFTKEYS_READ_EXIT__READ; + priority = KCBSPriority; + cancel = ETrue; + break; + case EMissedCallsNotification: + resource = R_MISSED_CALLS_NOTE; + softkeys = R_AVKON_SOFTKEYS_SHOW_EXIT__SHOW; + priority = KMissedCallsPriority; + cancel = ETrue; + SetNcnFlag(ETrue); + break; + case ENewMessagesNotification: + resource = R_NEW_MESSAGES_NOTE; + softkeys = R_AVKON_SOFTKEYS_SHOW_EXIT__SHOW; + priority = KNewMessagesPriority; + cancel = ETrue; + break; + case ENewMailNotification: + resource = R_NEW_MAIL_NOTE; + softkeys = R_AVKON_SOFTKEYS_SHOW_EXIT__SHOW; + priority = KNewEmailPriority; + cancel = ETrue; + break; + case EChatMessageNotification: + resource = R_NEW_CHAT_MESSAGES_NOTE; + softkeys = R_AVKON_SOFTKEYS_SHOW_EXIT__SHOW; + priority = KChatMessagePriority; + cancel = ETrue; + break; + case ECustomSoftNotification: + { + resource = iCustomNoteParamsStack->iId; + softkeys = iCustomNoteParamsStack->iParamData->iSoftkeys; + priority = iCustomNoteParamsStack->iParamData->iPriority; + tone = iCustomNoteParamsStack->iParamData->iTone; + cancel = EFalse; + count = iCustomNoteParamsStack->iCount; + break; + } + default: + break; + }; + + if (cancel) + { + // Remove duplicate notes + RemoveByType(aType); + count = aCount; + } + + TSoftNoteEntry softNote; + softNote.iType = aType; + softNote.iCount = count; + +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin, Adding ungrouped:type %d,count %d "); + RDebug::Print(KDmsg,aType, count); +#endif + + if ( aType == ECustomSoftNotification ) + { + if( iCustomNoteParamsStack->iParamType == KAknSoftNotificationCustom ) + { + TFileName resourceFile; + CEikonEnv* environment = CEikonEnv::Static(); + resourceFile.Append(iCustomNoteParamsStack->iParamData->iResourceFile->Des()); + BaflUtils::NearestLanguageFile(environment->FsSession(),resourceFile); + + TRAPD( err, iCustomNoteParamsStack->iCoeResourceHandle = + environment->AddResourceFileL(resourceFile)); + + if ( err ) + { // couldn't load note resource, remove note from queue +#ifdef _DEBUG + _LIT(KDmsg2,"AknSoftNotificationPlugin,Resource loading failed: %s"); + RDebug::Print(KDmsg2,&resourceFile); +#endif + RemoveCustomNoteForId(resource); + return; + } + } + + if (iCustomNoteParamsStack->iSupportsGroupedform && IsGroupedFormed()) + { // don't add to global notes queue + softNote.iId = 0; // grouped, not in global notes queue + softNote.iCustomId = iCustomNoteParamsStack->iId; + iSoftNoteEntryList->AppendL(softNote); + ScheduleGroupedNotifierL(); + return; + } + } + + if( aType == ECustomSoftNotification && + iCustomNoteParamsStack->iParamType == KAknSoftNotificationDynamic ) + { + if( iCustomNoteParamsStack->iDynamicData ) + { + CAknDynamicNotificationData* data = + iCustomNoteParamsStack->iDynamicData; + softNote.iId = iGlobalNoteController->AddSoftNotificationL( + aText, + count, + data->Priority(), + data->Tone(), + data->LeftSoftkey(), + data->RightSoftkey(), + data->ImageData() ); + } + } + else + { + softNote.iId = iGlobalNoteController->AddSoftNotificationL(aText, resource, count, priority, + softkeys, tone ); + } + + if ( aType == ECustomSoftNotification ) + { + CAknSDData* sdData = iCustomNoteParamsStack->iParamData->iSecondaryDisplayData; + + if ( sdData ) + { + CAknSDData* cloneSDData = NULL; + cloneSDData = CAknSDData::NewL( sdData->iCategory, sdData->iDialogIdx, *(sdData->iAdditionalData) ); + CleanupStack::PushL( cloneSDData ); + + TBool sdDataSet = iGlobalNoteController->SetSDData( softNote.iId, cloneSDData ); + + if ( sdDataSet ) + { + CleanupStack::Pop( cloneSDData ); + } + else // cloneSDData ownership not transferred + { + CleanupStack::PopAndDestroy( cloneSDData ); + } + } + + iCustomNoteParamsStack->iNoteId = softNote.iId; + } + + iGlobalNoteController->TryDisplayNextNoteL(); + iSoftNoteEntryList->AppendL(softNote); + +#ifdef _DEBUG + _LIT(KDmsg3,"AknSoftNotificationPlugin, Added SoftNote:type %d,NoteId %d "); + RDebug::Print(KDmsg3,aType, softNote.iId); +#endif + } + + +void CAknSoftNotificationSubject::RemoveByType(TAknSoftNotificationType aType, TInt aId) + { + TInt count = iSoftNoteEntryList->Count(); + for (TInt ii=count-1; ii>=0; ii--) + { + TSoftNoteEntry& entry = (*iSoftNoteEntryList)[ii]; + + if ( ( aType != ECustomSoftNotification && entry.iType == aType) + || ( aId != 0 && entry.iType == ECustomSoftNotification && entry.iId == aId) ) + { + iGlobalNoteController->CancelNote(entry.iId, EFalse); + iSoftNoteEntryList->Delete(ii); + } + } + } + +void CAknSoftNotificationSubject::ClearAllNotes() + { +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin,ClearAllNotes"); + RDebug::Print(KDmsg); +#endif + + while ( iSoftNoteEntryList->Count()) + { + TSoftNoteEntry& entry = (*iSoftNoteEntryList)[0]; + if (entry.iId != 0) + { + iGlobalNoteController->CancelNote(entry.iId, EFalse); + } + iSoftNotificationAmounts[entry.iType] = 0; + iSoftNoteEntryList->Delete(0); + } + + CCustomNotifParams* params = iCustomNoteParamsStack; + while ( params ) + { + CCustomNotifParams* tmp = params; + params = params->iNext; + delete tmp; + } + iCustomNoteParamsStack = 0; + } + +// Used only with ungrouped notes +TAknSoftNotificationType CAknSoftNotificationSubject::TypeFromId(TInt aId) + { + TInt count = iSoftNoteEntryList->Count(); + for (TInt ii = count - 1; ii >= 0; ii--) + { + TSoftNoteEntry& entry = (*iSoftNoteEntryList)[ii]; + if (entry.iId == aId) + { + return entry.iType; + } + } + return ENoSoftNotification; + } + +// Used only with ungrouped notes +void CAknSoftNotificationSubject::CompleteId(TInt aId) + { + TInt count = iSoftNoteEntryList->Count(); + for (TInt ii=count-1; ii>=0; ii--) + { + TSoftNoteEntry& entry = (*iSoftNoteEntryList)[ii]; + if (entry.iId == aId) + { + // Set notification count to zero + iSoftNotificationAmounts[entry.iType] = 0; + iSoftNoteEntryList->Delete(ii); + RemoveCustomNoteForId(aId,ETrue); + iNotificationsSaved = EFalse; + return; + } + } + return; + } + +void CAknSoftNotificationSubject::SoftNoteCompleted(TInt aId, TInt aCommand) + { + TRAPD(err, DoSoftNoteCompletedL(aId, aCommand)); + if (err) + { + CEikonEnv::Static()->HandleError(err); + } + } + +void CAknSoftNotificationSubject::DoSoftNoteCompletedL(TInt aId, TInt aCommand) + { + TAknSoftNotificationType type = TypeFromId( aId ); + +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin,DoSoftNoteCompletedL:type %d,NoteId %d, command %d "); + RDebug::Print(KDmsg,type, aId, aCommand); +#endif + + if ( aCommand == EAknSoftkeyExit ) + { + if ( type == EMissedCallsNotification ) + { + SetNcnFlag(EFalse); + } + if( type == ECustomSoftNotification ) + { + CCustomNotifParams* params = SeekCustomNoteForId( aId, ETrue ); + if( params ) + { + HandleCustomNoteCanceledL( params, aCommand ); + } + } + CompleteId(aId); + SaveSoftNotificationsL(); + return; + } + + switch (type) + { + case ESelectNetworkNotification: + if (aCommand == EAknSoftkeyOk) + { + LaunchSelectNetworkAppL(); + CompleteId(aId); + } + break; + case EUnstructuredSSDataNotification: + if (aCommand == EAknSoftkeyRead || aCommand == EAknSoftkeyOk) + { + LaunchUSSDAppL(); + CompleteId(aId); + } + break; + case EVoiceMailNotification: + case ESeparateVoiceMailOnLine1Notification: + case ESeparateVoiceMailOnLine2Notification: + if (aCommand == EAknSoftkeyListen || aCommand == EAknSoftkeyOk) + { + LaunchNewVoiceMailAppL(type); + CompleteId(aId); + } + break; + case ECellBroadcastNotification: + if (aCommand == EAknSoftkeyRead || aCommand == EAknSoftkeyOk) + { + LaunchNewCbsAppL(); + CompleteId(aId); + } + break; + case EMissedCallsNotification: + if (aCommand == EAknSoftkeyShow || aCommand == EAknSoftkeyOk) + { + LaunchMissedCallsAppL(); + CompleteId(aId); + } + break; + case ENewMessagesNotification: + if (aCommand == EAknSoftkeyShow || aCommand == EAknSoftkeyOk) + { + LaunchNewMessagesAppL(); + CompleteId(aId); + } + break; + case ENewMailNotification: + if (aCommand == EAknSoftkeyShow || aCommand == EAknSoftkeyOk) + { + LaunchNewMailAppL(); + CompleteId(aId); + } + break; + case EChatMessageNotification: + if (aCommand == EAknSoftkeyShow || aCommand == EAknSoftkeyOk) + { + LaunchNewIMAppL(); + CompleteId(aId); + } + break; + case ECustomSoftNotification: + { + CCustomNotifParams* params = SeekCustomNoteForId(aId, ETrue); + if (params) + { + HandleCustomNoteCompletedL(params, aCommand); + CompleteId(aId); + } + } + break; + default: + // Note type something else, this should not be the case. + // Remove note from queue anyway. + CompleteId( aId ); + break; + } + SaveSoftNotificationsL(); + } + + +void CAknSoftNotificationSubject::HandleCustomNoteCompletedL(CCustomNotifParams* aParams, + TInt aCommand) + { + if (aParams->iHasViewInfo) + { + if ( aCommand == EAknSoftkeyOk || + aParams->iParamData->iAcceptSoftKey == aCommand ) + { + LaunchViewL( + ((aParams->iParamData->iPluralViewId != KNullViewId && aParams->iCount > 1)? + aParams->iParamData->iPluralViewId: + aParams->iParamData->iViewId), + + aParams->iParamData->iCustomMessageId, + aParams->ViewActivationMessage() ); + } + } + + // notify user event + if( aParams->iParamType == KAknSoftNotificationDynamic ) + { + if( aParams->EnableObserver() ) + { + iDynamicSoftNoteManager->IssueEvent( + aParams->iId, EAknDynamicSNoteEventAccepted, ETrue ); + } + } + } + +void CAknSoftNotificationSubject::HandleCustomNoteCanceledL( + CCustomNotifParams* aParams, TInt /*aCommand*/ ) + { + // notify user event + if( aParams->iParamType == KAknSoftNotificationDynamic ) + { + if( aParams->EnableObserver() ) + { + iDynamicSoftNoteManager->IssueEvent( + aParams->iId, EAknDynamicSNoteEventCanceled, ETrue ); + } + } + } + +// +// Sets shared data flag to indicate that NCN is active. +// This implementation sets this only for missed calls note. +// +void CAknSoftNotificationSubject::SetNcnFlag(TBool aValue) + { + CRepository* repository = NULL; + TRAPD(ret, repository = CRepository::NewL(KCRUidAvkon)); + if (ret == KErrNone) + { + ret = repository->Set(KAknNewContactsNoteActive, aValue); + } + delete repository; + } + + +// Handler function for ncn flag shared data state change. +TInt CAknSoftNotificationSubject::HandleNcnFlagStateChange(TAny* /* aPtr */) + { + return KErrNone; + } + +TBool CAknSoftNotificationSubject::ShowSoftNoteL(TInt aPriority, const TDesC& /*aText*/) + { + if (aPriority == KGroupedNotification) + { + ShowGroupedNotificationL(); + return ETrue; + } + return EFalse; + } + +TBool CAknSoftNotificationSubject::CancelSoftNote(TInt aPriority) + { + if (aPriority == KGroupedNotification) + { + if (iGroupedNote) + { + iGroupedNote->RemoveEditorIndicator(); + delete iGroupedNote; + iGroupedNote = NULL; + } + return ETrue; + } + return EFalse; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::ShowGroupedNotificationL() +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::ShowGroupedNotificationL() + { + if ( iGroupedNote ) + { + iGroupedNote->RemoveEditorIndicator(); + } + + CAknGroupedNotifierNote* note = new (ELeave) CAknGroupedNotifierNote(); + CleanupStack::PushL( note ); + note->ConstructL( this ); + + note->SetItemAmountL( + EMissedCalls, + iSoftNotificationAmounts[EMissedCallsNotification], + iLatestType == EMissedCallsNotification); + + note->SetItemAmountL( + ENewMessages, + iSoftNotificationAmounts[ENewMessagesNotification], + iLatestType == ENewMessagesNotification); + + note->SetItemAmountL( + ENewChatMsgs, + iSoftNotificationAmounts[EChatMessageNotification], + iLatestType == EChatMessageNotification); + + note->SetItemAmountL( + ENewMails, + iSoftNotificationAmounts[ENewMailNotification], + iLatestType == ENewMailNotification); + + CleanupStack::Pop( note ); + + note->ExecuteLD( R_GROUPED_SOFT_NOTIFICATION ); + + delete iGroupedNote; + iGroupedNote = note; + if ( iKeysLocked && note ) + { + iGroupedNote->ListBox()->View()->ItemDrawer()->SetFlags( + CListItemDrawer::EDisableHighlight ); + } + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::MessageNotifierShown() +// --------------------------------------------------------- +// +TBool CAknSoftNotificationSubject::MessageNotifierShown() + { + TBool messageNotifierActive( EFalse ); + + for ( TInt ii = 0; ii <= ECustomSoftNotification; ii++) + { + // Check that one of the message notifiers is first in the + // priority order (visible). + if (iSoftNotificationAmounts[ii] > 0) + { + if (ii == EMissedCallsNotification && IsGroupedFormed()) + { + continue; + } + if ( ii == ENewMessagesNotification || + ii == ENewMailNotification || + ii == ECustomSoftNotification ) // Email uses custom soft note. + { + messageNotifierActive = ETrue; + } + break; + } + } + + return messageNotifierActive; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::ButtonGroupContainer() +// --------------------------------------------------------- +// +CEikButtonGroupContainer* CAknSoftNotificationSubject::ButtonGroupContainer() + { + CEikButtonGroupContainer* container = NULL; + if ( iGroupedNote ) + { + container = &iGroupedNote->ButtonGroupContainer(); + } + return container; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::IsGroupedFormed() +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CAknSoftNotificationSubject::IsGroupedFormed() + { + TInt foundTypes = 0; + if (iSoftNotificationAmounts[EMissedCallsNotification]) + { + foundTypes++; + } + if (iSoftNotificationAmounts[ENewMessagesNotification]) + { + foundTypes++; + } + if (iSoftNotificationAmounts[EChatMessageNotification]) + { + foundTypes++; + } + if (iSoftNotificationAmounts[ENewMailNotification]) + { + foundTypes++; + } + + // check custom notes which support grouped form + CCustomNotifParams* params = iCustomNoteParamsStack; + for (;params;params = params->iNext) + { + if(params->iSupportsGroupedform) + { + foundTypes++; + } + } + + if (foundTypes > 1) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// ------------------------------------ +// From MAknGroupedNotifierNoteObserver +// Add items to grouped form +// ------------------------------------ +void CAknSoftNotificationSubject::AddItemsL( CDesCArray& aTexts, CArrayFix& aOrder ) + { + // check custom notes which support grouped form + CCustomNotifParams* params = iCustomNoteParamsStack; + for (;params;params = params->iNext) + { + if(params->iSupportsGroupedform) + { + if( params->iParamType == KAknSoftNotificationDynamic ) + { + if( params->iCount > 1 ) + { + // plural text needs to be formatted + TPtrC text( params->CustomText( params->iCount, ETrue ) ); + const TInt formatSpace = 11; // space needed for 'count' + HBufC* buf = HBufC::NewLC( text.Length() + formatSpace ); + buf->Des().Format( text, params->iCount ); + + aTexts.AppendL( *buf ); + aOrder.AppendL( params->iId ); + + CleanupStack::PopAndDestroy( buf ); + } + else + { + // append singular text + aTexts.AppendL( params->CustomText( params->iCount, ETrue ) ); + aOrder.AppendL( params->iId ); + } + } + else + { + // Load text + CCoeEnv* coe = CCoeEnv::Static(); + TResourceReader reader; + HBufC* buf = 0; + + // Resources are loaded in DisplayUngroupedNotifierL() + coe->CreateResourceReaderLC(reader, params->iParamData->iGroupedTextResourceId); + TInt stringResource = reader.ReadInt32(); + + // Handle Singular / plural + possible plural string w/o number tag + if (params->iCount == 1) + { + buf = coe->AllocReadResourceLC(stringResource); + } + else + { + stringResource = reader.ReadInt32(); + buf = coe->AllocReadResourceLC(stringResource); + _LIT(KNumberId, "%N"); + if (buf->Find(KNumberId) != KErrNotFound) + { + CleanupStack::PopAndDestroy(); + buf = 0; + buf = StringLoader::LoadLC(stringResource,params->iCount); + } + } + + // Add Text + aTexts.AppendL(buf->Des()); + // add order + aOrder.AppendL(params->iId); + + CleanupStack::PopAndDestroy( 2 ); // buf and reader + } + + + } + } + } + +// -------------------------------------------------- +// CAknSoftNotificationSubject::SoftkeysForCustomItem +// (other items were commented in a header). +// -------------------------------------------------- +void CAknSoftNotificationSubject::SoftkeysForCustomItem(TAknGroupedNotifierItem aCustomItem, + TInt& aSoftkeyResourceId, TInt& aAcceptKeyId, + TDes& aLeftSoftkey, + TDes& aRightSoftkey ) + { + CCustomNotifParams* params = SeekCustomNoteForId(aCustomItem, EFalse); + if( params ) + { + if( params->iParamType == KAknSoftNotificationCustom && + params->iParamData ) + { + aSoftkeyResourceId = params->iParamData->iSoftkeys; + aAcceptKeyId = params->iParamData->iAcceptSoftKey; + } + + if( params->iParamType == KAknSoftNotificationDynamic && + params->iDynamicData ) + { + TPtrC sk( params->iDynamicData->LeftSoftkey() ); + if( sk.Length() > 0 ) + { + aLeftSoftkey.Copy( sk.Left( aLeftSoftkey.MaxLength() ) ); + } + + sk.Set( params->iDynamicData->RightSoftkey() ); + if( sk.Length() > 0 ) + { + aRightSoftkey.Copy( sk.Left( aRightSoftkey.MaxLength() ) ); + } + + } + } + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::LaunchMissedCallsAppL() +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::LaunchMissedCallsAppL() + { + TPtrC8 msg(KLogsActivationMsg); + + TApaTaskList taskList( CCoeEnv::Static()->WsSession() ); + TApaTask task = taskList.FindApp( KUidLogs ); + + // close fsw in case it is active. + // this is needed because LaunchMissedCallsAppL doesn't call + // method LaunchViewL, which does the same + ((CAknCapAppServerAppUi*)(CEikonEnv::Static())->EikAppUi())-> + HandleResourceChangeL(KAknInternalFSWClose); // won't leave + + TInt err = KErrNone; + + if( task.Exists() ) //Logs already open. Request it to + { //activate the correct view + task.SendMessage( KUidLogs, msg ); // the uid has no meaning so just re-use existing + + // preventing from the flicker of log view, the view will activte ieself when receiving a message. + // task.BringToForeground(); + } + else //Start Logs and request it to activate + { //the correct view + TApaAppInfo appInfo; + RApaLsSession lsSession; + err = lsSession.Connect(); + + if ( err == KErrNone ) + { + CleanupClosePushL( lsSession ); + + if( lsSession.GetAppInfo( appInfo, KUidLogs ) == KErrNone ) + { + CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); + cmdLine->SetExecutableNameL( appInfo.iFullName ); + cmdLine->SetCommandL( EApaCommandRun ); + cmdLine->SetTailEndL( msg ); + + lsSession.StartApp( *cmdLine ); + CleanupStack::PopAndDestroy( cmdLine ); + } + + CleanupStack::PopAndDestroy(); // lsSession + } + else + { + User::LeaveIfError( err ); + } + } + + if ( err == KErrNone ) + { + // We'll assume that application was launched/activated succesfully + SetNcnFlag(EFalse); + } + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::LaunchNewMessagesAppL() +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::LaunchNewMessagesAppL() + { + TInt viewtype = 0; // Default is traditional Inbox + + if ( iMessagingRepository ) + { + // Read the messaging settings + iMessagingRepository->Get(KMessagingAppDefaultViewCRKey,viewtype); + } + + if ( viewtype == 1 ) // Launch conversations + { + LaunchViewL( + KConversationApplicationViewUid, + TUid::Uid(KConversationListViewUid), + KNullDesC8() ); + } + else // Launch traditional Inbox + { + LaunchViewL( + KMessagingCentreInboxView, + TUid::Uid(KMsvGlobalInBoxIndexEntryIdValue), + KNullDesC8() ); + } + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::LaunchNewMailAppL() +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::LaunchNewMailAppL() + { + // reactivate MCE main view with arbitrary UID + LaunchViewL( KMessagingCentreMainViewUid, TUid::Uid(1),KNullDesC8() ); + } + +void CAknSoftNotificationSubject::LaunchNewCbsAppL() + { + if ( iSoftNotificationAmounts[ECellBroadcastNotification] == 1) + { + LaunchViewL( KCbsApplicationUidMessageView, TUid::Uid(1), KNullDesC8() ); + } + else + { + LaunchViewL( KCbsApplicationUidTopicListView, TUid::Uid(1), KNullDesC8() ); + } + } + +void CAknSoftNotificationSubject::LaunchNewVoiceMailAppL(TInt aType) + { + TUid uid = {1}; // als line 1 or no als (TVmbxNumberEntry::EAlsLine1Entry) + if ( aType == ESeparateVoiceMailOnLine2Notification ) + { + uid.iUid = 2; // (TVmbxNumberEntry::EAlsLine2Entry) + } + + LaunchViewL( KSpeeddialVmbxDialUidView, uid, KExternalLaunch ); + } + +void CAknSoftNotificationSubject::LaunchSelectNetworkAppL() + { + LaunchViewL( KSelectNetworkAppUidView, TUid::Uid( KGSCustomActivateNetView ), KNullDesC8() ); + } + +void CAknSoftNotificationSubject::LaunchUSSDAppL() + { + } + +void CAknSoftNotificationSubject::LaunchViewL(const TVwsViewId& aViewId, TUid aCustomMessageId, + const TDesC8& aCustomMessage) + { + CCoeEnv::Static()->AppUi()->CreateActivateViewEventL(aViewId, aCustomMessageId, aCustomMessage); + + SaveSoftNotificationsL(); + + // close fsw in case it is active. + ((CAknCapAppServerAppUi*)(CEikonEnv::Static())->EikAppUi())->HandleResourceChangeL( + KAknInternalFSWClose); // won't leave + + // We assume that view switching was successful, change idle state to false: + delete iIdle; + iIdle = 0; + iIdle = CIdle::NewL(EPriorityLow); + iIdle->Start(TCallBack(SetIdleStateFalse, this)); + } + +TInt CAknSoftNotificationSubject::SetIdleStateFalse(TAny* aThis) + { + TRAPD( err, ((CAknSoftNotificationSubject*)aThis)->iGlobalNoteController-> + SetMaxDisplayPriorityL(KMinimumSoftNotePriority)) + if (!err) + { + ((CAknSoftNotificationSubject*)aThis)->iIdleStateActive = EFalse; + ((CAknCapAppServerAppUi*)(CEikonEnv::Static())->EikAppUi())->SetIdleActive( EFalse ); + } + return err; + } + +void CAknSoftNotificationSubject::SaveSoftNotificationsL() + { + // Save all soft notifications in case of power failure + if ( iNotificationsSaved ) // notifications haven't been loaded since saved i.e. no changes + { + return; + } + + TInt count = iSoftNoteEntryList->Count(); + RFs& fs = CEikonEnv::Static()->FsSession(); +#ifdef __COVER_DISPLAY + iCoverClient->CancelCommand(); + iCoverClient->ResetBuffer(); +#endif + if (count == 0) + { + // Nothing to save, delete any existing file + TInt err = fs.Delete(KAknSNFilename); + iNotificationsSaved = EFalse; +#ifdef __COVER_DISPLAY + // if deleted for the first time, inform the cover ui, + // otherwise the deletion returns KErrNotFound + if ( err == KErrNone ) + { + // inform the cover ui that there are no soft notifications + iCoverClient->BufStream().WriteInt32L(count); + iCoverClient->BufStream().CommitL(); + iCoverClient->IssueCommand(); + } +#endif + } + else + { + // Create new file and save soft notifications + RFileWriteStream file; + TInt err = file.Replace(fs, KAknSNFilename, EFileWrite); + // path may not yet exist in 3.0 (private directory). + if (err == KErrPathNotFound) + { + User::LeaveIfError(fs.MkDirAll(KAknSNFilename)); + User::LeaveIfError(file.Create(fs, KAknSNFilename, EFileWrite)); + } + + CleanupClosePushL(file); + file.WriteInt32L(count); + +#ifdef __COVER_DISPLAY + TBool groupedExists = EFalse; + iCoverClient->BufStream().WriteInt32L(count); +#endif + + // Save in reverse order so order of notifications with identical priority remains + for (TInt ii = count - 1; ii >= 0; ii--) + { + TSoftNoteEntry& entry = (*iSoftNoteEntryList)[ii]; + SaveNoteL(file, entry); + +#ifdef __COVER_DISPLAY + if (entry.iType == EShowGroupedNotification) + { + groupedExists = ETrue; + } + + iCoverClient->BufStream().WriteInt32L(entry.iType); + iCoverClient->BufStream().WriteInt32L(entry.iCount); +#endif + }; + +#ifdef __COVER_DISPLAY + + TUint8 customsWCoverDataCount( 0 ); + // we don't have actual count of custom params (nor ones with secondary display data..) + for (CCustomNotifParams* params = iCustomNoteParamsStack; params; params = params->iNext) + { + if (params->iParamData->iSecondaryDisplayData) + { + customsWCoverDataCount++; + } + } + + iCoverClient->BufStream().WriteInt8L(customsWCoverDataCount); + if (customsWCoverDataCount) + { + for (CCustomNotifParams* params = iCustomNoteParamsStack; params; params = params->iNext) + { + if (params->iParamData->iSecondaryDisplayData) + { + iCoverClient->BufStream() << *params->iParamData->iSecondaryDisplayData; + } + } + } + + if (groupedExists) + { + iCoverClient->BufStream().WriteInt32L(EMissedCallsNotification); + iCoverClient->BufStream().WriteInt32L(iSoftNotificationAmounts[EMissedCallsNotification]); + iCoverClient->BufStream().WriteInt32L(ENewMessagesNotification); + iCoverClient->BufStream().WriteInt32L(iSoftNotificationAmounts[ENewMessagesNotification]); + iCoverClient->BufStream().WriteInt32L(EChatMessageNotification); + iCoverClient->BufStream().WriteInt32L(iSoftNotificationAmounts[EChatMessageNotification]); + iCoverClient->BufStream().WriteInt32L(ENewMailNotification); + iCoverClient->BufStream().WriteInt32L(iSoftNotificationAmounts[ENewMailNotification]); + } + + iCoverClient->BufStream().CommitL(); + iCoverClient->IssueCommand(); +#endif + CleanupStack::PopAndDestroy(); // close file + iNotificationsSaved = ETrue; + } + } + + +void CAknSoftNotificationSubject::SaveNoteL(RWriteStream& aFile, TSoftNoteEntry& aEntry) + { + TInt plural = aEntry.iCount; + const TDesC& text = iGlobalNoteController->NoteText(aEntry.iId); + +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin,SaveNoteL:type %d,NoteId %d, count %d "); + RDebug::Print(KDmsg, aEntry.iType, aEntry.iId, plural); +#endif + + switch (aEntry.iType) + { + case ENetworkInformationNotification: + case EUnstructuredSSDataNotification: + aFile.WriteUint8L(aEntry.iType); + aFile << text; + break; + case ESelectNetworkNotification: + aFile.WriteUint8L(aEntry.iType); + break; + case ESeparateVoiceMailOnLine1Notification: + case ESeparateVoiceMailOnLine2Notification: + case ECellBroadcastNotification: + case EVoiceMailNotification: + case EMissedCallsNotification: + case ENewMessagesNotification: + case ENewMailNotification: + case EChatMessageNotification: + aFile.WriteUint8L(aEntry.iType); + aFile.WriteInt32L(plural); + break; + case EShowGroupedNotification: + aFile.WriteUint8L(aEntry.iType); + aFile.WriteInt32L(iSoftNotificationAmounts[EMissedCallsNotification]); + aFile.WriteInt32L(iSoftNotificationAmounts[ENewMessagesNotification]); + aFile.WriteInt32L(iSoftNotificationAmounts[EChatMessageNotification]); + aFile.WriteInt32L(iSoftNotificationAmounts[ENewMailNotification]); + break; + case ECustomSoftNotification: + { + CCustomNotifParams* params = 0; + if (aEntry.iId != 0 ) + { + params = SeekCustomNoteForId(aEntry.iId,ETrue); + } + else + { + params = SeekCustomNoteForId(aEntry.iCustomId); + } + + if ( params ) + { + aFile.WriteUint8L(aEntry.iType); + aFile.WriteInt16L(params->iCount); + aFile << *params; + } + } + break; + default: + break; + } + } + +void CAknSoftNotificationSubject::LoadAndQueueSoftNotesL() + { + if ( !iNotificationsSaved ) + { + return; + } + + RFs& fs = CEikonEnv::Static()->FsSession(); + RFileReadStream file; + + TInt err = file.Open(fs, KAknSNFilename, EFileRead); + if ( err != KErrNone ) + { + iNotificationsSaved =EFalse; + User::Leave(err); + } + + CleanupClosePushL(file); + + TInt count = file.ReadInt32L(); + + if ( count > 0 ) + { + ClearAllNotes(); + } + + for (TInt ii=0; ii text; + switch (type) + { + case ENetworkInformationNotification: + case EUnstructuredSSDataNotification: + aStream >> text; + break; + case ESeparateVoiceMailOnLine1Notification: + case ESeparateVoiceMailOnLine2Notification: + case ECellBroadcastNotification: + case EVoiceMailNotification: + case EMissedCallsNotification: + case ENewMessagesNotification: + case ENewMailNotification: + case EChatMessageNotification: + count = aStream.ReadInt32L(); + break; + case EShowGroupedNotification: + iSoftNotificationAmounts[EMissedCallsNotification] = aStream.ReadInt32L(); + iSoftNotificationAmounts[ENewMessagesNotification] = aStream.ReadInt32L(); + iSoftNotificationAmounts[EChatMessageNotification] = aStream.ReadInt32L(); + iSoftNotificationAmounts[ENewMailNotification] = aStream.ReadInt32L(); + break; + case ECustomSoftNotification: + { + count = aStream.ReadInt16L(); + AddNewCustomNoteL(aStream, count); + if( iCustomNoteParamsStack ) + { + TPtrC customTxt( iCustomNoteParamsStack->CustomText( count, EFalse ) ); + if( customTxt.Length() > 0 ) + { + text.Copy( customTxt.Left( text.MaxLength() ) ); + } + } + } + default: + break; + } + +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin,LoadNoteL:type %d, count %d "); + RDebug::Print(KDmsg,type, count); +#endif + + if (type != EShowGroupedNotification) + { + TBool countChanged = ( iSoftNotificationAmounts[type] != count ); + iSoftNotificationAmounts[type] = count; + UpdateNoteL(type, text, count, countChanged); + } + else + { + ScheduleGroupedNotifierL(); + } + } + + +TBool CAknSoftNotificationSubject::CheckIfAlreadyExists(TAknSoftNotificationType aType) + { + TInt count = iSoftNoteEntryList->Count(); + for (TInt ii=count-1; ii>=0; ii--) + { + TSoftNoteEntry& entry = (*iSoftNoteEntryList)[ii]; + if (entry.iType == aType) + { + return ETrue; + } + } + return EFalse; + } + + +TBool CAknSoftNotificationSubject::AutoLockEnabled() + { + return EFalse; + } + +void CAknSoftNotificationSubject::AddNewCustomNoteL( + RReadStream& readStream, TInt aCount, TBool aNewNote ) + { + AddNewCustomNoteL((RDesReadStream&)readStream, aCount, aNewNote ); + } + + +void CAknSoftNotificationSubject::AddNewCustomNoteL( + RDesReadStream& readStream, TInt aCount, TBool aNewNote ) + { + // Before adding, check if there is a note of this type + CCustomNotifParams* next = new (ELeave) CCustomNotifParams; + CleanupStack::PushL( next ); + readStream >> *next; + CCustomNotifParams* existing = SeekCustomNoteForId(next->iParamData->iNoteResourceId,EFalse); + if ( existing ) + { + existing->iCount = aCount; + CleanupStack::PopAndDestroy( next ); + return; + } + + // do the switch (append new entry to stack) + next->iNext = iCustomNoteParamsStack; + iCustomNoteParamsStack = next; + CleanupStack::Pop(); + + if( next->iParamType == KAknSoftNotificationDynamic ) + { + if( aNewNote ) + { + // if new note, then generate new id + next->iDynamicData->SetId( GenerateUniqueId() ); + } + next->iId = next->iDynamicData->Id(); + next->iHasViewInfo = ( KNullViewId != next->iDynamicData->ViewId() ); + next->iCount = aCount; + next->iNoteId = KErrNotFound; + next->iSupportsGroupedform = ( + next->iDynamicData->SingularLabelGroup().Length() > 0 || + next->iDynamicData->PluralLabelGroup().Length() > 0 ); + } + else // default + { + iCustomNoteParamsStack->iId = iCustomNoteParamsStack->iParamData->iNoteResourceId; + + iCustomNoteParamsStack->iHasViewInfo = ( + KNullViewId != iCustomNoteParamsStack->iParamData->iViewId); + + iCustomNoteParamsStack->iCount = aCount; + iCustomNoteParamsStack->iNoteId = KErrNotFound; + + iCustomNoteParamsStack->iSupportsGroupedform = + (iCustomNoteParamsStack->iParamData->iGroupedTextResourceId != 0); + } + } + +CCustomNotifParams* CAknSoftNotificationSubject::SeekCustomNoteForId(TInt aID, TBool aSeekByGNoteId) + { + CCustomNotifParams* params = iCustomNoteParamsStack; + + for (;params && (aID != (aSeekByGNoteId?params->iNoteId:params->iId));) + { + params = params->iNext; + } + + return params; + } + + +void CAknSoftNotificationSubject::RemoveCustomNoteForId(TInt aID, TBool aSeekByGNoteId) + { + CCustomNotifParams* params = iCustomNoteParamsStack; + + if ( !params ) + { + return; + } + + if ( aSeekByGNoteId ) + { + RemoveByType(ECustomSoftNotification, aID); + } + else + { // just remove entry from list + TInt count = iSoftNoteEntryList->Count(); + for (TInt ii=0; iiAt(ii).iCustomId == aID ) + { + iSoftNoteEntryList->Delete(ii); + break; + } + } + } + + if ( aID == (aSeekByGNoteId?params->iNoteId:params->iId)) // Remove first note on stack + { + iCustomNoteParamsStack = params->iNext; + delete params; + + if (!iCustomNoteParamsStack) + { + iSoftNotificationAmounts[ECustomSoftNotification] = 0; + } + + return; + } + + + for (;params->iNext && (aID != (aSeekByGNoteId?params->iNext->iNoteId:params->iNext->iId));) + { + params = params->iNext; + } + + if ( params->iNext ) // Found previous item + { + CCustomNotifParams* tmp = params->iNext; + params->iNext = tmp->iNext; + delete tmp; + } + + if (!iCustomNoteParamsStack) + { + iSoftNotificationAmounts[ECustomSoftNotification] = 0; + } + } + +void CAknPrivateSoftNoteParameters::InternalizeL( RReadStream& aStream ) + { + delete iResourceFile; + iResourceFile = 0; + TInt length = aStream.ReadInt32L(); + if ( length ) + { + iResourceFile = HBufC::NewL(length); + TPtr resptr( iResourceFile->Des() ); + aStream >> resptr; + } + + iNoteResourceId = aStream.ReadInt32L(); + iPriority = aStream.ReadInt32L(); + iSoftkeys = aStream.ReadInt32L(); + iTone = (CAknNoteDialog::TTone)aStream.ReadInt32L(); + + iViewId.iAppUid = TUid::Uid(aStream.ReadUint32L()); + iViewId.iViewUid = TUid::Uid(aStream.ReadUint32L()); + iCustomMessageId = TUid::Uid(aStream.ReadUint32L()); + iAcceptSoftKey = aStream.ReadInt32L(); + + iPluralViewId.iAppUid = TUid::Uid(aStream.ReadUint32L()); + iPluralViewId.iViewUid = TUid::Uid(aStream.ReadUint32L()); + iGroupedTextResourceId = aStream.ReadInt32L(); + + delete iViewActivationMsg; + iViewActivationMsg = 0; + length = aStream.ReadInt32L(); + if ( length != KErrNotFound ) + { + iViewActivationMsg = HBufC8::NewL(length); + TPtr8 ptr( iViewActivationMsg->Des() ); + aStream >> ptr; + } + + delete iSecondaryDisplayData; + iSecondaryDisplayData = 0; + + if (aStream.ReadInt8L()) // item has secondary display data + { + iSecondaryDisplayData = new (ELeave) CAknSDData(); + aStream >> *iSecondaryDisplayData; + } + } + +void CAknPrivateSoftNoteParameters::ExternalizeL( RWriteStream& aStream ) const + { + aStream.WriteInt32L(iResourceFile->Length()); + aStream << (*iResourceFile); + aStream.WriteInt32L(iNoteResourceId); + aStream.WriteInt32L(iPriority); + aStream.WriteInt32L(iSoftkeys); + aStream.WriteInt32L(iTone); + aStream.WriteUint32L(iViewId.iAppUid.iUid); + aStream.WriteUint32L(iViewId.iViewUid.iUid); + aStream.WriteUint32L(iCustomMessageId.iUid); + aStream.WriteInt32L(iAcceptSoftKey); + + aStream.WriteUint32L(iPluralViewId.iAppUid.iUid); + aStream.WriteUint32L(iPluralViewId.iViewUid.iUid); + aStream.WriteUint32L(iGroupedTextResourceId); + + if ( iViewActivationMsg ) // optional + { + aStream.WriteInt32L(iViewActivationMsg->Length()); + aStream << (*iViewActivationMsg); + } + else + { + aStream.WriteInt32L(KErrNotFound); + } + + if (iSecondaryDisplayData) + { + aStream.WriteInt8L(ETrue); + aStream << *iSecondaryDisplayData; + } + else + { + aStream.WriteInt8L(EFalse); + } + } + +void CAknSoftNotificationSubject::LaunchNewIMAppL() + { + LaunchViewL( KChatSpecificView, TUid::Uid(42), KNullDesC8() ); + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::LoadUniqueIdL +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::LoadUniqueIdL() + { + RFs& fs( CEikonEnv::Static()->FsSession() ); + + RFileReadStream file; + User::LeaveIfError( file.Open( fs, KAknDynamicIdFilename, EFileRead ) ); + + file.PushL(); + iUniqueIdCounter = file.ReadInt32L(); + CleanupStack::PopAndDestroy( &file ); + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::StoreUniqueIdL +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::StoreUniqueIdL() + { + RFs& fs( CEikonEnv::Static()->FsSession() ); + + RFileWriteStream file; + TInt err = file.Replace( fs, KAknDynamicIdFilename, EFileWrite ); + + if( err == KErrPathNotFound ) + { + // folder not found -> create it + User::LeaveIfError( fs.MkDirAll( KAknDynamicIdFilename ) ); + User::LeaveIfError( file.Create( fs, KAknDynamicIdFilename, EFileWrite ) ); + } + else + { +#ifdef _DEBUG + if( err ) + { + _LIT(KDmsg, "AknSoftNotificationPlugin,StoreUniqueIdL: error %d"); + RDebug::Print( KDmsg, err); + } +#endif + User::LeaveIfError( err ); + } + + file.PushL(); + file.WriteInt32L( iUniqueIdCounter ); + file.CommitL(); + CleanupStack::PopAndDestroy( &file ); + } + + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::GenerateUniqueId +// --------------------------------------------------------- +// +TInt CAknSoftNotificationSubject::GenerateUniqueId() + { + TInt failsafe = KMaxTInt; // prevent infinite loop + while( failsafe ) // loop until found or failsafe expires + { + // try next id. Disallow values below KMinimumUniqueId. + iUniqueIdCounter = Max( KMinimumUniqueId, iUniqueIdCounter + 1 ); + + // go through existing notes and verify that the id is not used + CCustomNotifParams* params = iCustomNoteParamsStack; + while( params && params->iId != iUniqueIdCounter ) + { + params = params->iNext; + } + + if( !params ) + { + // Unique id found + break; + } + + --failsafe; + } + + // Store new id always when it has changed. We can't do anything if the + // saving fails, so we just ignore the error. + TRAPD( err, StoreUniqueIdL() ); + if( err ) + { +#ifdef _DEBUG + _LIT(KDmsg, "AknSoftNotificationPlugin,GenerateUniqueId: save error %d"); + RDebug::Print( KDmsg, err ); +#endif //_DEBUG + } + + return iUniqueIdCounter; + } + +// --------------------------------------------------------- +// CAknSoftNotificationSubject::WriteResponse +// --------------------------------------------------------- +// +void CAknSoftNotificationSubject::WriteResponse( + TDes8& aResponse, TInt aNoteId ) const + { + TPckg response( aNoteId ); + aResponse.Copy( response.Left( aResponse.MaxLength() ) ); + } + +// End of File