diff -r 000000000000 -r 2f259fa3e83a uifw/AknGlobalUI/OldStyleNotif/Src/AknSystemPopup.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AknGlobalUI/OldStyleNotif/Src/AknSystemPopup.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,2530 @@ +/* +* 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: System soft notifications. +* +*/ + + +#include +#include +#include "AknSystemPopup.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "AknNotifyPlugin.hrh" +#include +#include +#include + +#include +#include +#include + +#include +#include // for icon to skin conversion + +#include +#include "AknCapServerEntry.h" +#include +#include + +#include +#include +#include +#include "GlobalWindowPriorities.h" +#include "aknmessagereaderlongpressdetector.h" // CAknMessageReaderLongPressDetector + +#include // KCoreAppUIsAutolockStatus + +#include "AknDynamicNotificationData.h" +#include "AknPrivateImageLoader.h" +#include +#include + +#ifdef RD_UI_TRANSITION_EFFECTS_POPUPS + + #include + #include + +#endif + + +const TInt KGlobalNoteGranularity = 4; // Initialize with space for 4 notes + +const TInt KMaxSoftNotePriority = 3000; +const TInt KMaxAlarmNotePriority = 4000; +const TInt KMaxNotePriority = 5000; +const TInt KAlarmNotePriority = 3095; + +// class CGlobalNoteInfo + +CGlobalNoteInfo::CGlobalNoteInfo() : + iSoftkeys( 0 ), + iGraphic( -1 ), + iAnimation( 0 ), + iPlural( 0 ), + iAsync( EFalse ), + iTextProcessing( ETrue ), + iSDData(NULL), + iGlobalPopupPriority(0) + { + } + +CGlobalNoteInfo::~CGlobalNoteInfo() + { + delete iSDData; + } + +// class CAknGlobalNoteDialog + + +CAknGlobalNoteDialog::CAknGlobalNoteDialog(MGlobalNoteObserver* aObserver) +:iObserver(aObserver), iPreviousNoteId( KErrNotFound ) + { + iCommand = KErrCancel; + } + +void CAknGlobalNoteDialog::ConstructL() + { + ConstructSleepingDialogL(R_GLOBAL_NOTE); + } + +CAknGlobalNoteDialog::~CAknGlobalNoteDialog() + { + delete iImageLoader; + } + +TBool CAknGlobalNoteDialog::OkToExitL(TInt aButtonId) + { + + ((CAknCapAppServerAppUi*) CEikonEnv::Static()->AppUi())->SetIsShortTimeGlobalNoteDisplaying(EFalse); + + if ( (iControlType == R_PERMANENT_CONTROL) || + (iControlType == R_WAIT_CONTROL && iSoftkeys == R_AVKON_SOFTKEYS_EMPTY) ) + { + return EFalse; + } + + else if ( iIsAlarm ) + { + // Don't let an empty command through. + if ( aButtonId == EAknSoftkeyEmpty ) + { + return EFalse; + } + + CEikButtonGroupContainer& bgc = ButtonGroupContainer(); + + if ( aButtonId == EAlertSilence ) + { + if ( iSoftkeys == R_ALERT_SOFTKEYS_STOP_SILENT__OPEN ) + { + iSoftkeys = R_ALERT_SOFTKEYS_STOP_SNOOZE__OPEN; + } + else // R_ALERT_SOFTKEYS_STOP_SILENT + { + iSoftkeys = R_ALERT_SOFTKEYS_STOP_SNOOZE; + } + bgc.SetCommandSetL( iSoftkeys ); + bgc.ActivateL(); + bgc.MakeVisible( ETrue ); + bgc.DrawNow(); + iObserver->GlobalNoteCompleted( EAlertSilence ); + return EFalse; + } + + // make sure that rsk will be visible next time + // (this is actually a CBA fault but anyway). + else if ( iSoftkeys == R_ALERT_SOFTKEYS_STOP_SNOOZE && + !bgc.IsCommandVisible( EAlertSnooze ) ) + { + bgc.MakeCommandVisible( EAlertSnooze, ETrue ); + } + + if ( aButtonId == EAlertOpen ) + { + if ( iSoftkeys == R_ALERT_SOFTKEYS_STOP_SILENT__OPEN || + iSoftkeys == R_ALERT_SOFTKEYS_STOP_SNOOZE__OPEN || + iSoftkeys == R_ALERT_SOFTKEYS_STOP_SNOOZE ) + { + iSoftkeys = R_ALERT_SOFTKEYS_STOP_SNOOZE; + } + else if ( iSoftkeys == R_ALERT_SOFTKEYS_STOP_SILENT ) + { + iSoftkeys = R_ALERT_SOFTKEYS_STOP_SILENT ; + } + else // R_ALERT_SOFTKEYS_STOP_EMPTY__OPEN + { + iSoftkeys = R_ALERT_SOFTKEYS_STOP_EMPTY__EMPTY; + } + + bgc.SetCommandSetL( iSoftkeys ); + bgc.ActivateL(); + bgc.MakeVisible( ETrue ); + bgc.DrawNow(); + iObserver->GlobalNoteCompleted( EAlertOpen ); + return EFalse; + } + } + + iCommand = aButtonId; + NextNoteOrExit(); + return ETrue; + } + + +void CAknGlobalNoteDialog::PreLayoutDynInitL() + { + delete iTimer; + iTimer = NULL; + if ( iTimeoutInMicroseconds != ENoTimeout ) + { + iTimer = CPeriodic::NewL(0); + iTimer->Start(iTimeoutInMicroseconds, iTimeoutInMicroseconds, + TCallBack(CallNextNoteOrExit,this)); + } + + TransferControlAttributes(); // Ensure that new layout will be done + + if (iIsSoftNotification && iObserver->IsAppsKeyLocked() ) + { + iObserver->SetAppsKeyLocked( EFalse ); + } + } + +void CAknGlobalNoteDialog::HandleResourceChange(TInt aType) + { + if ( aType == KAknsMessageSkinChange ) + { + iPreviousAnimation = 0; // reload next animation always + } + + CAknStaticNoteDialog::HandleResourceChange(aType); + } + + +void CAknGlobalNoteDialog::PostLayoutDynInitL() + { + CEikButtonGroupContainer& bgc = ButtonGroupContainer(); + + if ( iSoftkeys ) + { + bgc.SetCommandSetL(iSoftkeys); + MEikButtonGroup* buttonGrp = bgc.ButtonGroup(); + if( buttonGrp ) + { + if( iSoftkeyLeft.Length() > 0 ) + { + bgc.SetCommandL( buttonGrp->CommandId( + CEikButtonGroupContainer::ELeftSoftkeyPosition ), + iSoftkeyLeft ); + } + if( iSoftkeyRight.Length() > 0 ) + { + bgc.SetCommandL( buttonGrp->CommandId( + CEikButtonGroupContainer::ERightSoftkeyPosition ), + iSoftkeyRight ); + } + + if (AknLayoutUtils::PenEnabled()) + { + if (iIsSoftNotification && iAutoLock) + { + bgc.MakeCommandVisible(buttonGrp->CommandId(CEikButtonGroupContainer::ELeftSoftkeyPosition), EFalse); + bgc.MakeCommandVisible(buttonGrp->CommandId(CEikButtonGroupContainer::ERightSoftkeyPosition), EFalse); + } + else + { + if (!bgc.IsCommandVisible(buttonGrp->CommandId(CEikButtonGroupContainer::ELeftSoftkeyPosition))) + bgc.MakeCommandVisible(buttonGrp->CommandId(CEikButtonGroupContainer::ELeftSoftkeyPosition), ETrue); + if (!bgc.IsCommandVisible(buttonGrp->CommandId(CEikButtonGroupContainer::ERightSoftkeyPosition))) + bgc.MakeCommandVisible(buttonGrp->CommandId(CEikButtonGroupContainer::ERightSoftkeyPosition), ETrue); + } + } + } + } + + CAknStaticNoteDialog::PostLayoutDynInitL(); + + if ( iIsSoftNotification && (iAutoLock > EAutolockOff) ) + { // members below exist always when dialog exists, + // LockKeys can be called multiple w/o problems, but as a optimisation, lets not + if (!((CAknGlobalNoteSubject*)iObserver)->iKeyLockController->IsKeyLockEnabled()) + { + ((CAknGlobalNoteSubject*)iObserver)->iKeyLockController->LockKeys(ETrue); + } + } + + // Play the note note here, since RunLD will not be called (which is where tones are normally played from) + PlayTone(); + if (!iObserver->IsAppsKeyLocked() && !iIsSoftNotification) + { + if(iTimeoutInMicroseconds != EShortTimeout) + { + iObserver->SetAppsKeyLocked( ETrue ); + } + } + } + +TKeyResponse CAknGlobalNoteDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + if (iIsSoftNotification && aType == EEventKey) + { + // Send numbers keys to phone app, and bring it for foreground + if ((aKeyEvent.iCode >= '0' && aKeyEvent.iCode <= '9') + || aKeyEvent.iCode == '#' + || aKeyEvent.iCode == '*') + { + if( aKeyEvent.iRepeats == 0 ) + { + MAknPhoneKeyForwarder* keyf = STATIC_CAST( + CAknCapAppServerAppUi*, + CEikonEnv::Static()->AppUi())->AsKeyForwarder(); + + keyf->ForwardKeyToPhoneAppL(aKeyEvent); + + ((CAknGlobalNoteSubject*)iObserver)->SetMaxDisplayPriorityL(KMinimumSoftNotePriority); + } + return EKeyWasConsumed; + } + else if ( aKeyEvent.iCode == EKeyEnter ) + { + TKeyEvent ccpuStart = { EKeyOK, EStdKeyDevice3, 0, 0 }; + CCoeEnv::Static()->SimulateKeyEventL( ccpuStart, EEventKey ); + return EKeyWasConsumed; + } + else if ( aKeyEvent.iCode != EKeyOK ) //Other keys don't remove soft notification. + { + if ( aKeyEvent.iCode == EKeyNo ) + { + iCommand = EAknSoftkeyExit; + NextNoteOrExit(); + } + + return EKeyWasConsumed; + } + } + + if (aKeyEvent.iCode == EKeyEscape) + { + return EKeyWasNotConsumed; + } + + // Don't consume send key for displaying the dialer view, + // only for soft notification. + if (aKeyEvent.iScanCode == EStdKeyYes && iIsSoftNotification) + { + return EKeyWasNotConsumed; + } + + if (iControlType == R_PERMANENT_CONTROL || + iControlType == R_WAIT_CONTROL || + iTimeoutInMicroseconds == ENoTimeout) + { + return EKeyWasConsumed; + } + + // Any keypress dismissed other types of notes + if (aType == EEventKey) + { + NextNoteOrExit(); + } + return EKeyWasConsumed; + } + +TBool CAknGlobalNoteDialog::CallNextNoteOrExit(TAny* aThis) + { + STATIC_CAST(CAknGlobalNoteDialog*, aThis)->NextNoteOrExit(); + return ETrue; + } + +void CAknGlobalNoteDialog::NextNoteOrExit(TBool aDirectExit) + { + // If there is another global note waiting, show the next note, + // otherwise put the global note back to sleep + delete iTimer; + iTimer = NULL; + + // if there are more notes on queue, don't release the apps key + if (iObserver->IsAppsKeyLocked() && !iObserver->NoteWaiting()) + { + iObserver->SetAppsKeyLocked( EFalse ); + } + + // Set borders back to zero + SetNumberOfBorders(0); + + // to make sure that we don't leave RSK hidden even if OkToExitL is not called + if (aDirectExit) + { + CEikButtonGroupContainer& bgc = ButtonGroupContainer(); + if ( iSoftkeys == R_ALERT_SOFTKEYS_STOP_SNOOZE && + !bgc.IsCommandVisible( EAlertSnooze ) ) + { + bgc.MakeCommandVisible( EAlertSnooze, ETrue ); + } + } + +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + SetGloballyCapturing( EFalse ); + SetPointerCapture( EFalse ); + } +#endif // RD_SCALABLE_UI_V2 + + ExitSleepingDialog(); + iDialogActive = EFalse; + + TRAP_IGNORE( PublishDialogL( 0 ) ); // to reset + iObserver->GlobalNoteCompleted(iCommand); + } + +void CAknGlobalNoteDialog::RemoveCurrentNote() + { + // Removes the current global note, so that a non-note dialog can be + // shown + delete iTimer; + iTimer = NULL; +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + SetGloballyCapturing( EFalse ); + SetPointerCapture( EFalse ); + } +#endif // RD_SCALABLE_UI_V2 + + ExitSleepingDialog(); + iDialogActive = EFalse; + } + +void CAknGlobalNoteDialog::UpdateNoteAndDisplayL( CGlobalNoteInfo* aInfo ) + { + TInt notePriority = aInfo->iPriority; + TInt noteResource = aInfo->iResourceId; + TInt noteSoftkeys = aInfo->iSoftkeys; + TInt notePlural = aInfo->iPlural; + TInt noteGraphic = aInfo->iGraphic; + TInt noteGraphicM = aInfo->iGraphicMask; + TInt noteAnimation = aInfo->iAnimation; + CAknNoteDialog::TTimeout noteTimeout = aInfo->iTimeOut; + CAknNoteDialog::TTone noteTone = aInfo->iTone; + CAknSDData* noteSDData = aInfo->iSDData; + + iCommand = KErrCancel; + iTimeoutInMicroseconds = noteTimeout; + iControlType = noteResource; + + iIsSoftNotification = ( + notePriority >= KMinimumSoftNotePriority && + notePriority <= KMaxSoftNotePriority ); + + //close the blank screen when global note display + if (noteTimeout == EShortTimeout) + { + CAknCapAppServerAppUi* pAppui = + (CAknCapAppServerAppUi*) CEikonEnv::Static()->AppUi(); + pAppui->SetIsShortTimeGlobalNoteDisplaying(ETrue); + } + +#ifdef RD_UI_TRANSITION_EFFECTS_POPUPS + + // use soft notify context + if( iIsSoftNotification ) + { + GfxTransEffect::Register( this, KGfxSystemNotificationControlUid ); + } + else // must register other possible contexts (global notes) + { + class TResIdToContext + { + public: + TInt iResId; + TUid iContextId; + }; + + TResIdToContext mapArray[] = + { + R_INFORMATION_CONTROL, KGfxInformationNoteControlUid, + R_WARNING_CONTROL, KGfxWarningNoteControlUid, + R_CONFIRMATION_CONTROL, KGfxConfirmationNoteControlUid, + R_ERROR_CONTROL, KGfxErrorNoteControlUid, + R_WAIT_CONTROL, KGfxWaitNoteControlUid, + R_BATTERY_CHARGING_CONTROL,KGfxSystemNotifBatteryControlUid, + R_BATTERY_NOT_CHARGING_CONTROL,KGfxSystemNotifBatteryControlUid, + R_BATTERY_FULL_CONTROL,KGfxSystemNotifBatteryControlUid, + R_BATTERY_LOW_CONTROL,KGfxSystemNotifBatteryControlUid, + R_RECHARGE_BATTERY_CONTROL,KGfxSystemNotifBatteryControlUid + }; + + TUid contextId = TUid::Uid(0); + for( TInt i = 0; iiAlmFlag == EAskWakeUp); + iSoftkeys = noteSoftkeys; + +#ifdef RD_SCALABLE_UI_V2 + if ( AknLayoutUtils::PenEnabled() ) + { + SetGloballyCapturing( ETrue ); + SetPointerCapture( ETrue ); + } +#endif + + if ( !iSoftkeys ) + { + if (iControlType == R_WAIT_CONTROL) + { + iSoftkeys = R_AVKON_SOFTKEYS_CANCEL; + } + else if ( notePriority != KAlarmNotePriority ) + { + iSoftkeys = R_AVKON_SOFTKEYS_EMPTY; + } + } + + iSoftkeyLeft.Set( aInfo->iLeftSK ); + iSoftkeyRight.Set( aInfo->iRightSK ); + + if (aInfo->iImage.Length() <= 0) + { + // Exit sleeping dialog firstly for preventing from ui flicker. + ExitSleepingDialog(); + } + + if( iPreviousNoteId != aInfo->iNoteId && + aInfo->iImage.Length() > 0 && + !noteResource ) + { + // this is dynamic soft notification with new image. + // Set dialogs layout with resource. + noteResource = R_NEW_DYNAMIC_NOTIFIER_NOTE; + } + + CAknNoteControl* note = STATIC_CAST( CAknNoteControl*, Control(ENPIGlobalNote) ); + if ( noteResource ) + { + TResourceReader reader; + iEikonEnv->CreateResourceReaderLC( reader, noteResource ); + note->ConstructFromResourceL( reader ); + CleanupStack::PopAndDestroy(); // reader + } + + SetTextProcessing( aInfo->iTextProcessing ); + + if ( aInfo->iText.Length() ) + { + SetTextL( aInfo->iText ); + } + if ( notePlural > 0 ) + { + SetTextNumberL( notePlural ); + } + + // check whether this is the same note we showed last time + TBool noteChanged = ( iPreviousNoteId != aInfo->iNoteId ); + iPreviousNoteId = aInfo->iNoteId; + TBool asyncImageLoading = EFalse; // delay dialog until image is loaded + + if( aInfo->iImage.Length() > 0 ) + { + // Only load image if the notification has changed + if( noteChanged ) + { + // Get icon size from LAF + TRect mainpane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, mainpane ); + TAknLayoutRect noterect; + noterect.LayoutRect( mainpane, AknLayout::popup_note_image_window() ); + TAknLayoutRect gfxrect; + gfxrect.LayoutRect( noterect.Rect(), + AknLayout::Note_with_an_image_pop_up_window_elements_Line_12() ); + + // Create image loader + if( !iImageLoader ) + { + iImageLoader = CAknPrivateImageLoader::NewL( + CEikonEnv::Static()->FsSession(), *this ); + } + + // load icon + TRAPD( err, + iImageLoader->LoadIconL( aInfo->iImage, gfxrect.Rect().Size() ) ); + + if( !err ) + { + // we're loading image -> delay dialog until loading is done + asyncImageLoading = ETrue; + } + else + { + // when image loading fails, we reset the dialog's image + SetImageL( NULL ); + } + } + } + if ( noteGraphic != -1 ) + { + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + + CEikImage* image = new (ELeave) CEikImage; + CleanupStack::PushL( image ); + + //Check For Skin Icon + TAknsItemID id = CAknNoteAttributes::GetSkinnedBitmapID( noteGraphic ); + + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + + AknsUtils::CreateIconL( + skin, + id, + bitmap, + mask, + KAvkonBitmapFile, + noteGraphic, + noteGraphicM); + + image->SetPicture( bitmap, mask ); + SetImageL( image ); + CleanupStack::Pop( image ); + } + + if ( noteAnimation != 0 ) + { + // don't reset animation if it is already loaded + if ( noteResource || iPreviousAnimation != noteAnimation ) + { + note->SetAnimationL( noteAnimation ); + iPreviousAnimation = noteAnimation; + } + } + else + iPreviousAnimation = 0; + + iTone = noteTone; + + // We don't want play tone twice (In case some other note appears on top of this note). + noteTone = CAknNoteDialog::ENoTone; + + ReportUserActivity(); + + if ( noteSDData ) + { + // secondary display data has been published + PublishDialogL( noteSDData->iDialogIdx, noteSDData->iCategory ); + } + else + { + // or the global note is unidentified + PublishDialogL( EAknUnidentifiedNote, KAknSecondaryDisplayCategory ); + } + + CAknMediatorFacade* cover_info = AknMediatorFacade(this); + if (cover_info) // cover ui defined + { + if ( noteSDData && noteSDData->iAdditionalData ) + {// information from client + cover_info->BufStream() << *(noteSDData->iAdditionalData); + } + else if (iIsAlarm && iObserver->AlarmData()) + { // share detailled alarm info + TBuf8 buf; + + // copy constructor should do just fine, but just to make sure + buf.Append((const TUint8*)iObserver->AlarmData(),sizeof(SAknAlarmPSInfo)); + + cover_info->BufStream() << buf; + } + else + { // default information about global note + SAknGlobalNoteData params; + params.iResourceId = noteResource; + params.iTimeOut = noteTimeout; + params.iTone = noteTone; + params.iTextLength = aInfo->iText.Length(); + params.iSoftkeys = noteSoftkeys; + params.iImage.iImageId = noteGraphic; + params.iImage.iImageMaskId = noteGraphicM; + params.iAnimation = noteAnimation; + params.iPlural = notePlural; + TPckgBuf buf(params); + cover_info->BufStream() << buf; + cover_info->BufStream() << aInfo->iText; + } + cover_info->BufStream().CommitL(); + } + + AknGlobalPopupPriorityController::SetPopupPriorityL(*this, aInfo->iGlobalPopupPriority); + + iDialogActive = ETrue; + + // invalidate whole dialog area + if( !asyncImageLoading ) + { + // DrawDeferred(); + RouseSleepingDialog(); + } + } + +void CAknGlobalNoteDialog::ImageLoadSuccess( CEikImage* aImage ) + { + // set image + TRAP_IGNORE(SetImageL(aImage)); + + if( iDialogActive ) + { + // Draw dialog + DrawDeferred(); + RouseSleepingDialog(); + } + + delete iImageLoader; + iImageLoader = NULL; + } + +void CAknGlobalNoteDialog::ImageLoadError( TInt /*aError*/ ) + { + // clear previous image + TRAP_IGNORE(SetImageL(NULL)); + + if( iDialogActive ) + { + // Draw dialog without image + DrawDeferred(); + RouseSleepingDialog(); + } + + delete iImageLoader; + iImageLoader = NULL; + } + +void CAknGlobalNoteDialog::SetAutoLock(TBool aAutoLock) + { + iAutoLock = aAutoLock; + } + +RWindow& CAknGlobalNoteDialog::GlobalNoteWindow() + { + return Window(); + } + +void CAknGlobalNoteDialog::CEikDialog_Reserved_1() + { + } + +void CAknGlobalNoteDialog::CEikDialog_Reserved_2() + { + } + +void CAknGlobalNoteDialog::CAknNoteDialog_Reserved() + { + } + +void CAknGlobalNoteDialog::CAknStaticNoteDialog_Reserved() + { + } + +void CAknGlobalNoteDialog::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + if (Rect().Contains(aPointerEvent.iPosition) && (aPointerEvent.iType == TPointerEvent::EButton1Up) + && iIsAlarm) + { + if (!iIsAlarmWakeup) + { + CEikDialog::TryExitL(EAlertOpen); + } + } + else if ((iSoftkeys == R_AVKON_SOFTKEYS_EMPTY) && + (iTimeoutInMicroseconds != ENoTimeout) && + (aPointerEvent.iType == TPointerEvent::EButton1Up)) + { + CEikDialog::TryExitL(EAknSoftkeyExit); + } + else + { + CAknStaticNoteDialog::HandlePointerEventL(aPointerEvent); + } + } + +// class CAknGlobalNoteSubject + +CAknGlobalNoteSubject* CAknGlobalNoteSubject::NewL( + MAknKeyLockController* aKeyLockController ) + { + CAknGlobalNoteSubject* self = + new (ELeave) CAknGlobalNoteSubject(aKeyLockController); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +CAknGlobalNoteSubject::CAknGlobalNoteSubject(MAknKeyLockController* aKeyLockController) +:iKeyLockController(aKeyLockController),iNoteId(1), iMaxDisplayPriority(KMaxTInt), + iMaxDisplayPriorityLimit(KMaxSoftNotePriority) + { + } + +void CAknGlobalNoteSubject::ConstructL() + { + iGlobalNoteList = new(ELeave) CArrayFixFlat(KGlobalNoteGranularity); + iGlobalNoteList->SetReserveL(KGlobalNoteGranularity); + iDisplayingNoteId = KErrNotFound; + + // Construct the emergency call support here, but it is not activated until a + // permanent note is started + iEcsDetector = CAknEcsDetector::NewL(); + iKeyLockController->AddObserverL(this); + + // Setup a async callback for displaying the next note in the queue + // This allows the next note to be displayed from the destructor of + // a previous note, but the callback will execute only when the + // destructor has finished + TCallBack callback(CallDisplayNextNote, this); + iDisplayCallback = new(ELeave)CAsyncCallBack(callback, CActive::EPriorityHigh); + + iGlobalNote = new(ELeave)CAknGlobalNoteDialog(this); + iGlobalNote->ConstructL(); + + iDialogController = CNotifierDialogController::NewL(this); + SetNotificationDialogObserver(iDialogController); + + // Make sure that server has a pointer to the dialog stack + STATIC_CAST(CAknCapServer*,CEikonEnv::Static()->AppServer())-> + SetGlobalNoteController(iDialogController); + + STATIC_CAST(CAknCapAppServerAppUi*,CEikonEnv::Static()->AppUi())-> + iGlobalNotesController = this; + + // Only initialize message reader long press detector + // if message reader has been installed + if ( CAknMessageReaderLongPressDetector::MessageReaderInstalled() ) + { + iMessageReaderLongPressDetector = CAknMessageReaderLongPressDetector::NewL( &iGlobalNote->ButtonGroupContainer(), iGlobalNote->GlobalNoteWindow() ); + STATIC_CAST(CAknCapAppServerAppUi*,CEikonEnv::Static()->AppUi())-> + iMessageReaderLongPressDetector = iMessageReaderLongPressDetector; + } + + // Set-up autolock status change notification. + User::LeaveIfError(iAutolockStatusProperty.Attach( + KPSUidCoreApplicationUIs, + KCoreAppUIsAutolockStatus)); + + iAutolockStatusSubscriber = new (ELeave) CSubscriber( + TCallBack(AutolockStatusNotificationL, this), + iAutolockStatusProperty); + + iAutolockStatusSubscriber->Subscribe(); + + // Get the initial value. + iAutolockStatusProperty.Get(iAutoLock); + + iGlobalNote->SetAutoLock(iAutoLock > EAutolockOff); + + iAlarmData = new SAknAlarmPSInfo; + User::LeaveIfNull(iAlarmData); + } + + +TPtrC8 CAknGlobalNoteSubject::StartL(const TDesC8& aBuffer) + { + RDesReadStream readStream(aBuffer); + + // TInt32 takes four chars. + if ( aBuffer.Length() < 4 ) + { + User::Leave(KErrArgument); + } + else + { + TInt signature = readStream.ReadInt32L(); + + if ( signature == KAKNNOTIFIERSIGNATURE_GETNOTEID ) + { + iRetPckg().iNoteId = iNoteId++; + return iRetPckg; + } + + if ( signature != KAKNNOTIFIERSIGNATURE ) + { + User::Leave(KErrArgument); + } + } + + TBuf text; // We mustn't use heap... + + TInt type = readStream.ReadInt16L(); + readStream >> text; + + TInt priority = readStream.ReadInt16L(); + TInt softkeys = readStream.ReadInt32L(); + TInt graphic = readStream.ReadInt16L(); + TInt graphicMask = readStream.ReadInt16L(); + TInt animation = readStream.ReadInt32L(); + TInt tone = readStream.ReadInt16L(); + TChar adapterTypesUsed = readStream.ReadInt8L(); + TChar textProcessing = readStream.ReadInt8L(); + TInt preallocatedNoteId = readStream.ReadInt32L(); + CAknSDData* secondaryDisplayInfo = new (ELeave) CAknSDData(); + CleanupStack::PushL(secondaryDisplayInfo); + if (readStream.ReadInt8L()) + { + readStream >> *secondaryDisplayInfo; + } + + TInt noteId = KErrNotFound; + + if ( type == EAknGlobalRechargeBatteryNote || + type == EAknGlobalBatteryLowNote|| + type == EAknGlobalBatteryFullNote|| + type == EAknGlobalChargingNote || + type == EAknGlobalNotChargingNote || + type == EAknGlobalBatteryFullUnplugNote || + type == EAknGlobalUnplugChargerNote ) + { + if (iNotesDisabled) + { + priority = KMaxAlarmNotePriority; + tone = CAknNoteDialog::ENoTone; + } + secondaryDisplayInfo->iDialogIdx = type; + // fw will set correct category uid automatically + secondaryDisplayInfo->iCategory = KNullUid; + } + + // make sure that error notes w/o timeout do not get hidden behinds soft notifications + if (type == EAknGlobalErrorNote || type == EAknGlobalWarningNote ) + { + // We alter only default priority, and do it only if note does not have timeout. + if (priority == 0 && softkeys != 0 ) + { + priority = KMaxSoftNotePriority+1; + } + } + + switch ( type ) + { + case EAknGlobalInformationNote: + noteId = AddNoteToQueueL( R_INFORMATION_CONTROL, + text, + priority, + CAknNoteDialog::ELongTimeout, + CAknNoteDialog::EConfirmationTone, + tone, + graphic, + graphicMask, + animation, + softkeys, + preallocatedNoteId ); + break; + + case EAknGlobalWarningNote: + noteId = AddNoteToQueueL( R_WARNING_CONTROL, + text, + priority, + CAknNoteDialog::ELongTimeout, + CAknNoteDialog::EWarningTone, + tone, + graphic, + graphicMask, + animation, + softkeys, + preallocatedNoteId ); + break; + + case EAknGlobalConfirmationNote: + noteId = AddNoteToQueueL( R_CONFIRMATION_CONTROL, + text, + priority, + CAknNoteDialog::EShortTimeout, + CAknNoteDialog::EConfirmationTone, + tone, + graphic, + graphicMask, + animation, + softkeys, + preallocatedNoteId ); + break; + + case EAknGlobalErrorNote: + noteId = AddNoteToQueueL( R_ERROR_CONTROL, + text, + priority, + CAknNoteDialog::ELongTimeout, + CAknNoteDialog::EErrorTone, + tone, + graphic, + graphicMask, + animation, + softkeys, + preallocatedNoteId ); + break; + + case EAknGlobalWaitNote: + noteId = AddNoteToQueueL( R_WAIT_CONTROL, + text, + priority, + CAknNoteDialog::ENoTimeout, + CAknNoteDialog::ENoTone, + tone, + graphic, + graphicMask, + animation, + softkeys, + preallocatedNoteId ); + break; + + case EAknGlobalPermanentNote: + noteId = AddNoteToQueueL( R_PERMANENT_CONTROL, + text, + priority, + CAknNoteDialog::ENoTimeout, + CAknNoteDialog::ENoTone, + tone, + graphic, + graphicMask, + animation, + 0, // softkeys + preallocatedNoteId ); + break; + + case EAknGlobalChargingNote: + noteId = AddNoteToQueueL( R_BATTERY_CHARGING_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + case EAknGlobalNotChargingNote: + noteId = AddNoteToQueueL( R_BATTERY_NOT_CHARGING_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + case EAknGlobalBatteryFullNote: + noteId = AddNoteToQueueL( R_BATTERY_FULL_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + case EAknGlobalBatteryLowNote: + noteId = AddNoteToQueueL( R_BATTERY_LOW_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + case EAknGlobalRechargeBatteryNote: + noteId = AddNoteToQueueL( R_RECHARGE_BATTERY_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + case EAknCancelGlobalNote: + CancelNote( priority ); + break; + + case EAknGlobalTextNote: + noteId = AddNoteToQueueL( R_NOTE_PLAIN_TEXT_CONTROL, + text, + priority, + CAknNoteDialog::ELongTimeout, + CAknNoteDialog::EConfirmationTone, + tone, + graphic, + graphicMask, + animation, + softkeys, + preallocatedNoteId ); + break; + + case EAknGlobalBatteryFullUnplugNote: + noteId = AddNoteToQueueL( R_BATTERY_FULL_UNPLUG_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + case EAknGlobalUnplugChargerNote: + noteId = AddNoteToQueueL( R_UNPLUG_CHARGER_CONTROL, + priority, + tone, + preallocatedNoteId ); + break; + + default: + break; + } + + if( type == EAknGlobalChargingNote || + type == EAknGlobalNotChargingNote || + type == EAknGlobalBatteryFullNote || + type == EAknGlobalBatteryLowNote || + type == EAknGlobalRechargeBatteryNote || + type == EAknGlobalBatteryFullUnplugNote || + type == EAknGlobalUnplugChargerNote ) + { + Note(noteId)->iGlobalPopupPriority = 1; + } + + TBool sdDataSet( EFalse ); + + if ( noteId != KErrNotFound && iGlobalNoteList ) // we are not in cancel state + { + TInt index = NoteIndex(noteId); + if ( index != KErrNotFound && iGlobalNoteList->Count() > index ) + { + // Is global note adapter used. + (*iGlobalNoteList)[index]->iIsFromAdapter = adapterTypesUsed; + (*iGlobalNoteList)[index]->iTextProcessing = textProcessing; + } + if ( index != KErrNotFound && secondaryDisplayInfo->iDialogIdx != 0 ) + { + sdDataSet = SetSDData( noteId, secondaryDisplayInfo ); + } + } + + if ( sdDataSet ) + { + CleanupStack::Pop( secondaryDisplayInfo ); + } + else // secondaryDisplayInfo ownership not transferred + { + CleanupStack::PopAndDestroy( secondaryDisplayInfo ); + } + +#ifdef _DEBUG + _LIT(KDmsg, "AknGlobalNote, StartL:id %d,type %d,prior %d"); + RDebug::Print(KDmsg,noteId,type,priority); +#endif + + TryDisplayNextNoteL(ETrue); + + iRetPckg().iNoteId = noteId; + return iRetPckg; + } + +CAknGlobalNoteSubject::~CAknGlobalNoteSubject() + { + // Stop subscribe for autolock status changes in PubSub. + if (iAutolockStatusSubscriber) + { + iAutolockStatusSubscriber->StopSubscribe(); + } + iAutolockStatusProperty.Close(); + delete iAutolockStatusSubscriber; + + delete iDialogController; + delete iGlobalNote; + delete iDisplayCallback; + iKeyLockController->RemoveObserver(this); + delete iEcsDetector; + + if ( iGlobalNoteList ) + { + TInt count = iGlobalNoteList->Count(); + for ( TInt i = count - 1; i > KErrNotFound; i-- ) + { + delete (*iGlobalNoteList)[i]; + } + delete iGlobalNoteList; + } + + delete iIdle; + delete iAlarmData; + + if ( iMessageReaderLongPressDetector ) + { + delete iMessageReaderLongPressDetector; + } + } + +void CAknGlobalNoteSubject::Release() + { + delete this; + } + +CAknGlobalNoteSubject::TNotifierInfo CAknGlobalNoteSubject::RegisterL() + { + iInfo.iUid = KAknGlobalNoteUid; + iInfo.iChannel=EAknNotifierChannelNote; + iInfo.iPriority = ENotifierPriorityVHigh; + return iInfo; + } + +CAknGlobalNoteSubject::TNotifierInfo CAknGlobalNoteSubject::Info() const + { + return iInfo; + } + +void CAknGlobalNoteSubject::StartL(const TDesC8& aBuffer, TInt /*aReplySlot*/, + const RMessagePtr2& aMessage) + { + RDesReadStream readStream(aBuffer); + + // TInt32 takes four chars. + if (aBuffer.Length() >= 4 && readStream.ReadInt32L() == KAKNNOTIFIERSIGNATURE_GETNOTEID) + { + aMessage.Complete(KErrNotSupported); + return; + } + + StartL(aBuffer); + TInt noteId = iRetPckg().iNoteId; + + if (noteId == KErrNotFound) + { + aMessage.Complete(KErrNone); + return; + } + + // returns correct info or panics, no need to error handling here + CGlobalNoteInfo* info = Note(noteId); + + info->iAsync = ETrue; + info->iMessage = aMessage; +#ifdef _DEBUG + _LIT(KDmsg, "AknGlobalNote, async StartL:id %d,prior %d"); + RDebug::Print(KDmsg,noteId,info->iPriority); +#endif + } + +void CAknGlobalNoteSubject::Cancel() + { + CancelOustandingRequests(); + } + +TPtrC8 CAknGlobalNoteSubject::UpdateL(const TDesC8& aBuffer) + { +#ifdef _DEBUG + _LIT(KDmsg,"AknGlobalNote, UpdateL"); + RDebug::Print(KDmsg); +#endif + return StartL(aBuffer); + } + +void CAknGlobalNoteSubject::KeyPressed(const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/) + { + } + +TInt CAknGlobalNoteSubject::AddNoteToQueueL( + TInt aResourceId, + const TDesC& aText, + TInt aPriority, + CAknNoteDialog::TTimeout aTimeout, + CAknNoteDialog::TTone aDefaultTone, + TInt aUserTone, + TInt aGraphic, + TInt aGraphicMask, + TInt aAnimation, + TInt aSoftkeys) + { + return AddNoteToQueueL( + aResourceId, + aText, + aPriority, + aTimeout, + aDefaultTone, + aUserTone, + aGraphic, + aGraphicMask, + aAnimation, + aSoftkeys, + 0); + } + +TInt CAknGlobalNoteSubject::AddNoteToQueueL( + TInt aResourceId, + const TDesC& aText, + TInt aPriority, + CAknNoteDialog::TTimeout aTimeout, + CAknNoteDialog::TTone aDefaultTone, + TInt aUserTone, + TInt aGraphic, + TInt aGraphicMask, + TInt aAnimation, + TInt aSoftkeys, + TInt aPreAllocatedNoteId) + { + if (!IsPreallocatedNoteIdValid(aPreAllocatedNoteId)) + { + return KErrNotFound; + } + + // Check that note doesn't already exist + TInt count = iGlobalNoteList->Count(); + for (TInt ii=0; iiiResourceId == aResourceId) + { + if (info->iText.Compare(aText) == 0) + { + return KErrNotFound; + } + } + } + + CGlobalNoteInfo* info = new (ELeave) CGlobalNoteInfo(); + + if (aPreAllocatedNoteId) + { + info->iNoteId = aPreAllocatedNoteId; + } + else + { + info->iNoteId = iNoteId++; + } + + info->iResourceId = aResourceId; + info->iTimeOut = aTimeout; + if (aSoftkeys) + { + info->iTimeOut = CAknNoteDialog::ENoTimeout; + } + CAknNoteDialog::TTone tone = aDefaultTone; + if (aUserTone != -1) + { + tone = (CAknNoteDialog::TTone)aUserTone; + } + info->iTone = tone; + info->iText.Copy(aText); + info->iPriority = aPriority; + info->iSoftkeys = aSoftkeys; + info->iGraphic = aGraphic; + info->iGraphicMask = aGraphicMask; + info->iAnimation = aAnimation; + iGlobalNoteList->AppendL( info ); + + iGlobalNote->SetNumberOfBorders( StackCount() ); + + return info->iNoteId; + } + +TInt CAknGlobalNoteSubject::AddNoteToQueueL(TInt aResourceId, TInt aPriority, TInt aTone, + TInt aPreAllocatedNoteId) + { + if (!IsPreallocatedNoteIdValid(aPreAllocatedNoteId)) + { + return KErrNotFound; + } + + // Check that note doesn't already exist + TInt count = iGlobalNoteList->Count(); + for (TInt ii=0; iiiResourceId == aResourceId) + { + return KErrNotFound; + } + } + + CGlobalNoteInfo* info = new (ELeave) CGlobalNoteInfo(); + + if (aPreAllocatedNoteId) + { + info->iNoteId = aPreAllocatedNoteId; + } + else + { + info->iNoteId = iNoteId++; + } + + info->iResourceId = aResourceId; + info->iTimeOut = CAknNoteDialog::EShortTimeout; + CAknNoteDialog::TTone tone = CAknNoteDialog::ENoTone; + if (aTone != -1) + { + tone = (CAknNoteDialog::TTone)aTone; + } + info->iTone = tone; + info->iPriority = aPriority; + iGlobalNoteList->AppendL( info ); + + iGlobalNote->SetNumberOfBorders( StackCount() ); + + return info->iNoteId; + } + + +TInt CAknGlobalNoteSubject::AddSoftNotificationL(const TDesC& aText, TInt aResource, TInt aCount, + TInt aPriority, TInt aSoftkeys, TInt aTone) + { + CGlobalNoteInfo* info = new (ELeave) CGlobalNoteInfo(); + info->iNoteId = iNoteId++; + info->iText.Copy(aText); + info->iResourceId = aResource; + info->iTimeOut = CAknNoteDialog::ENoTimeout; + info->iTone = CAknNoteDialog::TTone(aTone); + info->iPriority = aPriority; + info->iSoftkeys = aSoftkeys; + info->iPlural = aCount; + iGlobalNoteList->AppendL( info ); + + iGlobalNote->SetNumberOfBorders( StackCount() ); + + return info->iNoteId; + } + +TInt CAknGlobalNoteSubject::AddSoftNotificationL( + const TDesC& aText, + TInt aCount, + TInt aPriority, + TInt aTone, + const TDesC& aLeftSK, + const TDesC& aRightSK, + const TDesC8& aImage ) + { + CGlobalNoteInfo* info = new (ELeave) CGlobalNoteInfo(); + CleanupStack::PushL( info ); + info->iNoteId = iNoteId++; + // use resource if no image is defined to clear the previous image + info->iResourceId = + aImage.Length() > 0 ? 0 : R_NEW_DYNAMIC_NOTIFIER_NOTE; + info->iText.Copy( aText.Left( KGlobalNoteTextLength ) ); + info->iSoftkeys = R_AVKON_SOFTKEYS_SHOW_EXIT__SHOW; + info->iTimeOut = CAknNoteDialog::ENoTimeout; + info->iTone = CAknNoteDialog::TTone(aTone); + info->iPriority = aPriority; + info->iPlural = aCount; + + // extended custom parameters + info->iImage.Set( aImage ); + info->iRightSK.Set( aRightSK ); + info->iLeftSK.Set( aLeftSK ); + + iGlobalNoteList->AppendL( info ); + CleanupStack::Pop( info ); + iGlobalNote->SetNumberOfBorders( StackCount() ); + return info->iNoteId; + } + +void CAknGlobalNoteSubject::TryDisplayNextNoteL(TBool aShowAsynch) + { + if ( iGlobalNoteList && iGlobalNoteList->Count() == 0 ) + { + return; + } + +#ifdef _DEBUG + _LIT(KDmsg, "AknGlobalNote, TryDisplayNextNoteL:displaying %d"); + RDebug::Print(KDmsg,iDisplayingNoteId); +#endif + + if (iDisplayingNoteId == KErrNotFound) + { + // Note current note, so display as normal + if (!aShowAsynch) + { + DisplayNextNoteL(); + } + else if (!iDisplayCallback->IsActive()) + { + iDisplayCallback->CallBack(); + } + } + else + { + TInt highIndex; + TInt highPriority; + CGlobalNoteInfo* info = Note( iDisplayingNoteId ); + // we don't want add any note on top of alarm note ( at least currently ) + if (info->iPriority == KAlarmNotePriority ) + { + return; + } + + HighestPriorityNote(highIndex, highPriority); + if (highPriority > iCurrentPriority) + { + if (iSoftNoteObserver) + { + iSoftNoteObserver->CancelSoftNote(info->iPriority); + } + if (iNotificationDialogObserver ) + { + iNotificationDialogObserver->CancelSoftNote(info->iPriority); + } + iDisplayingNoteId = KErrNotFound; + if (!aShowAsynch) + { + DisplayNextNoteL(); + iCurrentPriority = highPriority; + } + else if (!iDisplayCallback->IsActive()) + { + iDisplayCallback->CallBack(); + } + } + } + } + + +void CAknGlobalNoteSubject::HighestPriorityNote(TInt& aIndex, TInt& aPriority) + { + // Priority of notes: + // First added non-waiting note in queue has priority + // If no non-waiting notes added, first added waiting note + // Notes with a prioriy higher than iMaxDisplayPriority are ignored + TInt priority = KMinTInt; + TInt index = KErrNotFound; + TInt count = iGlobalNoteList->Count(); + for (TInt ii=0; iiiPriority < iMaxDisplayPriority || info->iPriority > iMaxDisplayPriorityLimit) + { + TInt actualPriority = info->iPriority; + if (info->iTimeOut != CAknNoteDialog::ENoTimeout) + { + // Boost priority of non-waiting notes, so that + // they interrupt soft notifications + actualPriority += KMaxNotePriority; + } + if (actualPriority > priority) + { + priority = actualPriority; + index = ii; + } + } + } + aIndex = index; + aPriority = priority; + } + + +void CAknGlobalNoteSubject::DisplayNextNoteL() + { + if (iDisplayCallback->IsActive()) + { + iDisplayCallback->Cancel(); + } + + if ( iMessageReaderLongPressDetector ) + { + iMessageReaderLongPressDetector->SoftNotifierVisible( EFalse ); + } + + // Count permanent notes and see if ECS should be turned on/off + TInt permanentNoteCount = PermanentNotesCount(); + if ( permanentNoteCount > 0 ) + { + iEcsDetector->ConnectToEventSource(); + } + else + { + iEcsDetector->CloseEventSource(); + iEcsDetector->Reset(); // Ecs queue is cleared; keys up til here are forgotten + } + + TInt count = iGlobalNoteList->Count(); + if (iDisplayingNoteId != KErrNotFound || count == 0) + { + return; + } + + // Find next highest priority note + + TInt priority = KMinTInt; + TInt index = 0; + HighestPriorityNote(index, priority); + if (index == KErrNotFound) + { + return; + } + + CGlobalNoteInfo* info = (*iGlobalNoteList)[index]; + + if (iSoftNoteObserver) + { + + // activate long press detector if soft notification is shown + if ( iMessageReaderLongPressDetector ) + { + TBool isSoftNotification = ( info->iPriority >= KMinimumSoftNotePriority && + info->iPriority <= KMaxSoftNotePriority ); + if ( isSoftNotification ) + { + iMessageReaderLongPressDetector->SoftNotifierVisible( ETrue ); + } + } + if (iSoftNoteObserver->ShowSoftNoteL( info->iPriority, info->iText ) ) + { + // Soft note is being displayed instead + iDisplayingNoteId = info->iNoteId; +#ifdef _DEBUG + _LIT(KDmsg, "AknGlobalNote, DisplayNextNoteL:SoftNote %d"); + RDebug::Print( KDmsg, info->iPriority ); +#endif + return; + } + } + if (iNotificationDialogObserver) + { + if (iNotificationDialogObserver->ShowSoftNoteL(info->iPriority, info->iText)) + { + // Get rid of any current global note + iGlobalNote->RemoveCurrentNote(); + // Notifier note is being displayed instead + iDisplayingNoteId = info->iNoteId; +#ifdef _DEBUG + _LIT(KDmsg2, "AknGlobalNote, DisplayNextNoteL:Other type %d"); + RDebug::Print(KDmsg2,info->iPriority); +#endif + return; + } + } + + iGlobalNote->UpdateNoteAndDisplayL(info); + + // display stack indicator, if more than 1 note pending + iGlobalNote->SetNumberOfBorders(StackCount()); + + iDisplayingNoteId = info->iNoteId; + iCurrentPriority = priority; +#ifdef _DEBUG + _LIT(KDmsg3, "AknGlobalNote, DisplayNextNoteL:Normal: %d"); + RDebug::Print(KDmsg3,info->iPriority); +#endif + } + + +void CAknGlobalNoteSubject::GlobalNoteCompleted(TInt aCommand) + { + iCurrentPriority = KMinTInt; + if (iDisplayingNoteId == KErrNotFound) + { + return; + } + CGlobalNoteInfo* info = Note( iDisplayingNoteId ); + +#ifdef _DEBUG + _LIT(KDmsg, "AknGlobalNote, NoteCompleted:Command %d, id %d"); + RDebug::Print(KDmsg,aCommand, info->iNoteId); +#endif + + if ( iSoftNoteObserver && info->iPriority >= KMinimumSoftNotePriority) + { + iSoftNoteObserver->SoftNoteCompleted(info->iNoteId, aCommand); + } + if (iNotificationDialogObserver) + { + iNotificationDialogObserver->SoftNoteCompleted(info->iNoteId, aCommand); + if ( aCommand == EAlertSilence ) + { + CAknMediatorFacade* coverData = AknMediatorFacade( iGlobalNote ); + if ( coverData ) + { + SAknIntegerUpdate s = + { + EAknGlobalNotifierUpdateSoftkeys, + R_ALERT_SOFTKEYS_STOP_SNOOZE + }; + + TPckg pck(s); + coverData->ResetBuffer(); + coverData->BufStream() << pck; + TRAP_IGNORE( + coverData->BufStream().CommitL(); + coverData->PostUpdatedDataL(); + ); + } + return; + } + else if ( aCommand == EAlertOpen ) + { + // Works the same way as the "silence" key...don't complete/close the note. + return; + } + } + if (info->iAsync) + { + if (info->iIsFromAdapter) // if adapter is in use, we need to change softkey + { // enumeration according to GlobalNote.h + if ( aCommand == EAknSoftkeyOk ) + { + info->iMessage.Complete( 1 ); // EGlobalNoteResultOk = 1, + } + else if ( aCommand == EAknSoftkeyExit ) + { + info->iMessage.Complete( 2 ); // EGlobalNoteResultExit = 2, + } + else if ( aCommand == EAknSoftkeyCancel ) + { + info->iMessage.Complete( 3 ); // EGlobalNoteResultCancel = 3, + } + else if ( aCommand == EAknSoftkeyBack ) + { + info->iMessage.Complete( 4 ); // EGlobalNoteResultBack = 4, + } + else if ( aCommand == EAknSoftkeyClose ) + { + info->iMessage.Complete( 5 ); // EGlobalNoteResultClose = 5, + } + else if ( aCommand == EAknSoftkeyQuit ) + { + info->iMessage.Complete( 6 ); // EGlobalNoteResultQuit = 6, + } + else if ( aCommand == EAknSoftkeyYes ) + { + info->iMessage.Complete( 7 ); // EGlobalNoteResultYes = 7, + } + else if ( aCommand == EAknSoftkeyNo ) + { + info->iMessage.Complete( 8 ); // EGlobalNoteResultNo = 8, + } + else if ( aCommand == EAknSoftkeyShow ) + { + info->iMessage.Complete( 9 ); // EGlobalNoteResultAnswer = 9 + } + else // Default: + { + info->iMessage.Complete(KErrCancel); + } + } + else // return S60 softkeyId + { + info->iMessage.Complete(aCommand); + } + info->iAsync = EFalse; + } + + iGlobalNoteList->Delete( NoteIndex( iDisplayingNoteId ) ); + delete info; + info = NULL; + + iDisplayingNoteId = KErrNotFound; + + // Call DisplayNextNoteL via a async callback. + iDisplayCallback->CallBack(); + } + +TInt CAknGlobalNoteSubject::CallDisplayNextNote( TAny* aThis ) + { + // Need to trap this, since this may be called from destructor of + // prevous global note. + // Worst situation is that global note will not be displayed immediately, + // and sit in queue until another global note is displayed. + TRAP_IGNORE( STATIC_CAST( CAknGlobalNoteSubject*, aThis )->DisplayNextNoteL() ); + return 0; + } + +void CAknGlobalNoteSubject::SetMessageNotifierObserver( MAknMessageNotifierObserver* aMessageNotifierObserver ) + { + if ( iMessageReaderLongPressDetector ) + { + iMessageReaderLongPressDetector->SetMessageNotifierObserver( aMessageNotifierObserver ); + } + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CancelNote +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::CancelNote( TInt aNoteId, TBool aShowNext ) + { + CancelNote( aNoteId, aShowNext, ETrue ); + } + + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CancelNote +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::CancelNote( TInt aNoteId, + TBool aShowNext, + TBool aDeleteNoteInfo ) + { + +#ifdef _DEBUG + _LIT( KDmsg, "AknGlobalNote, NoteCompleted:Command %d, id %d" ); + RDebug::Print( KDmsg, aNoteId ); +#endif + + TInt noteIndex = NoteIndex( aNoteId ); + if ( noteIndex == KErrNotFound ) + { + return; + } + + CGlobalNoteInfo* info = Note( aNoteId ); + const TInt priority = info->iPriority; + + if ( iNotificationDialogObserver ) + { + iNotificationDialogObserver->CancelSoftNote( priority ); + } + + if ( iDisplayingNoteId == aNoteId ) + { + // Deleting will also remove note from stack. + if ( !aShowNext ) + { + if ( info->iAsync ) + { + info->iMessage.Complete( KErrCancel ); + info->iAsync = EFalse; + } + + iGlobalNoteList->Delete( noteIndex ); + + if ( aDeleteNoteInfo ) + { + // aDeleteNoteInfo specifies whether or not the note + // is really discarded. + delete info; + info = NULL; + // info should not be accessed any more. + } + + iDisplayingNoteId = KErrNotFound; + } + + if ( iSoftNoteObserver ) + { + // disable long press detector when notification is closed from the screen + if ( iMessageReaderLongPressDetector ) + { + iMessageReaderLongPressDetector->SoftNotifierVisible( EFalse ); + } + TBool noteDeleted = iSoftNoteObserver->CancelSoftNote( priority ); + if ( noteDeleted && aShowNext ) // grouped note was deleted so remove it from queue + { + iGlobalNoteList->Delete( noteIndex ); + + if ( aDeleteNoteInfo ) + { + // aDeleteNoteInfo specifies whether or not the note + // is really discarded. + delete info; + info = NULL; + // info should not be accessed any more. + } + + iDisplayingNoteId = KErrNotFound; + } + } + + iGlobalNote->NextNoteOrExit( ETrue ); + iDisplayingNoteId = KErrNotFound; + } + else + { + // If not displayed, remove note from stack. + if ( info->iAsync ) + { + info->iMessage.Complete( KErrCancel ); + info->iAsync = EFalse; + } + + iGlobalNoteList->Delete( noteIndex ); + + if ( aDeleteNoteInfo ) + { + // aDeleteNoteInfo specifies whether or not the note + // is really discarded. + delete info; + info = NULL; + // info should not be accessed any more. + } + + // Change stack indicator. Display stack indicator, if more than 1 note pending. + iGlobalNote->SetNumberOfBorders( StackCount() ); + } + } + + +void CAknGlobalNoteSubject::CancelOustandingRequests() + { + TInt count = iGlobalNoteList->Count(); + for (TInt ii = count - 1; ii >= 0; ii--) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if ( info->iAsync ) + { + // Only cancelled if the cancelling thread is where the + // global note originated from. + RThread t; + TInt err = info->iMessage.Client(t); + CAknCapAppServerAppUi* appUi = (CAknCapAppServerAppUi*) CEikonEnv::Static()->AppUi(); + if ( !err && ( appUi->iClientId == t.Id() ) ) + { + CancelNote( info->iNoteId ); + } + t.Close(); + } + } + } + + +void CAknGlobalNoteSubject::SetSoftNoteObserver(MSoftNotificationObserver* aObserver) + { + iSoftNoteObserver = aObserver; + } + +void CAknGlobalNoteSubject::SetNotificationDialogObserver(MSoftNotificationObserver* aObserver) + { + iNotificationDialogObserver = aObserver; + } + +TInt CAknGlobalNoteSubject::NotePlural(TInt aNoteId) + { + TInt count = iGlobalNoteList->Count(); + for (TInt ii = 0; ii < count; ii++) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if (info->iNoteId == aNoteId) + { + return info->iPlural; + } + } + return -1; + } + +const TDesC& CAknGlobalNoteSubject::NoteText(TInt aNoteId) + { + TInt count = iGlobalNoteList->Count(); + for (TInt ii = 0; ii < count; ii++) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if (info->iNoteId == aNoteId) + { + return info->iText; + } + } + return KNullDesC; + } + +void CAknGlobalNoteSubject::SetMaxDisplayPriorityL(TInt aPriority, TInt aDelay) + { +#ifdef _DEBUG + _LIT(KDmsg, "AknGlobalNote, SetMaxDisplayPriorityL: %d"); + RDebug::Print(KDmsg,aPriority); +#endif + + if (iNotesDisabled) + { + iPreviousDisplayPriority = aPriority; + return; + } + + iMaxDisplayPriority = aPriority; + if (iDisplayingNoteId == KErrNotFound) + { + if (aDelay > 0 && iGlobalNoteList->Count() > 0) + { + if (!iDisplayCallback->IsActive()) + { + iDisplayCallback->CallBack(); + } + return; + } + + TryDisplayNextNoteL(); + return; + } + + CGlobalNoteInfo* info = Note( iDisplayingNoteId ); + + if (info->iPriority >= iMaxDisplayPriority) + { + TBool async = info->iAsync; + // Displaying note is higher than max priority, so cancel it. + if ( async ) + { + // Leave note to queue, but remove it from display. + iDisplayingNoteId = KErrNotFound; + iGlobalNote->NextNoteOrExit(); + } + else + { + if ( info->iPriority == KAlarmNotePriority ) + { + // Idle states does not have any effect to alarm. + if ( iMaxDisplayPriority != KMinimumSoftNotePriority ) + { + CancelNote( info->iNoteId, EFalse ); + } + } + else + { + // All the others but alarm note are rescheduled. + CancelNote( info->iNoteId, EFalse, EFalse ); // remove from display, but + // don't delete info object, + // as it's appended back. + iGlobalNoteList->AppendL( info ); // add to queue + } + } + } + + else if ( iGlobalNoteList->Count() > 1 ) // there are other notifications on queue + { + TryDisplayNextNoteL(); + } + } + +TInt CAknGlobalNoteSubject::StackCount() + { + TInt total = 0; + TInt count = iGlobalNoteList->Count(); + for (TInt ii = 0; ii < count; ii++) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if (info->iPriority < iMaxDisplayPriority) + { + total++; + } + } + return total; + } + + +CGlobalNoteInfo* CAknGlobalNoteSubject::Note(TInt aNoteId) + { + TInt count = iGlobalNoteList->Count(); + for (TInt ii = 0; ii < count; ii++) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if (info->iNoteId == aNoteId) + { + return info; + } + } + return (*iGlobalNoteList)[0]; + } + + +TInt CAknGlobalNoteSubject::NoteIndex(TInt aNoteId) + { + TInt count = iGlobalNoteList->Count(); + for (TInt ii = 0; ii < count; ii++) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if ( info->iNoteId == aNoteId ) + { + return ii; + } + } + return KErrNotFound; + } + +TInt CAknGlobalNoteSubject::PermanentNotesCount() const + { + TInt permanentCount = 0; + TInt count = iGlobalNoteList->Count(); + for (TInt ii = 0; ii < count; ii++) + { + const CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if (info->iPriority < iMaxDisplayPriority) + if ( info->iResourceId == R_PERMANENT_CONTROL ) + { + permanentCount++; + } + } + return permanentCount; + } + +void CAknGlobalNoteSubject::KeyLockStatusChange(TKeyLockStatus aStatus) + { +#ifdef _DEBUG + RDebug::Print(_L("--KeyLockStatusChange aStatus [%d], NoteDisabled [%d], Previous [%d], Limit [%d], Max [%d]"), + aStatus, iNotesDisabled, iPreviousDisplayPriority, iMaxDisplayPriorityLimit, iMaxDisplayPriority); +#endif + + // Handle EKeyLockStopNotifications. + if (aStatus == EKeyLockStopNotifications) + { + if (!iNotesDisabled) + { + iPreviousDisplayPriority = iMaxDisplayPriority; + iMaxDisplayPriorityLimit = KMaxAlarmNotePriority; + // Ignore errors, just means next note may not display at present. + TRAP_IGNORE(SetMaxDisplayPriorityL(KMinTInt)); + iNotesDisabled = ETrue; +#ifdef _DEBUG + _LIT(KDmsg, "--DisableGlobalNotes"); + RDebug::Print(KDmsg); +#endif + } + } + // Handle EKeyLockAllowNotifications. + else if (aStatus == EKeyLockAllowNotifications) + { + if (iNotesDisabled) + { + iNotesDisabled = EFalse; + iMaxDisplayPriorityLimit = KMaxSoftNotePriority; + // Ignore errors, just means next note may not display at present. + TRAP_IGNORE( SetMaxDisplayPriorityL(iPreviousDisplayPriority)); +#ifdef _DEBUG + _LIT(KDmsg2, "--AllowGlobalNotes"); + RDebug::Print(KDmsg2); +#endif + } + } + // Handle EKeyLockCancelNotification. + else if (aStatus == EKeyLockCancelNotification) + { +#ifdef _DEBUG + _LIT(KDmsg3, "--CancelAllGlobalNotes"); + RDebug::Print(KDmsg3); +#endif + // First check to make sure. + if (iDisplayingNoteId >= 0) + { + CGlobalNoteInfo* info = Note(iDisplayingNoteId); + if (info->iResourceId == R_PERMANENT_CONTROL) + { + return; + } + } + + CancelNote(iDisplayingNoteId, EFalse); + + // Cancel all other queued notifications. + TInt count = iGlobalNoteList->Count(); + for (TInt ii = count - 1; ii >= 0; ii--) + { + CGlobalNoteInfo* info = (*iGlobalNoteList)[ii]; + if (info->iPriority < iMaxDisplayPriority && info->iResourceId != R_PERMANENT_CONTROL) + { + CancelNote(info->iNoteId, EFalse); + } + } + SetAppsKeyLocked( EFalse ); + } + // Handle EHideSoftNotifications. + else if ( aStatus == EHideSoftNotifications ) + { +#ifdef _DEBUG + _LIT(KDmsg4, "--HideSoftNotifications"); + RDebug::Print(KDmsg4); +#endif + TRAP_IGNORE(SetMaxDisplayPriorityL(KMinimumSoftNotePriority)); + } + // Handle EShowSoftNotifications. + else if ( aStatus == EShowSoftNotifications ) + { +#ifdef _DEBUG + _LIT(KDmsg5, "--AllowSoftNotifications"); + RDebug::Print(KDmsg5); +#endif + if (iNotesDisabled) + { + // After the max priority is set, we need to restore iNoteDisabled back to ETrue, + // otherwise, it will break EKeyLockAllowNotifications. + iNotesDisabled = EFalse; + TRAP_IGNORE(SetMaxDisplayPriorityL(KMaxTInt, 50000)); + iNotesDisabled = ETrue; + iPreviousDisplayPriority = KMaxTInt; + } + else + { + TRAP_IGNORE(SetMaxDisplayPriorityL(KMaxTInt, 50000)); + } + } + } + +TBool CAknGlobalNoteSubject::NoteWaiting() + { + TInt count = StackCount(); + if (count > 1 && iDisplayingNoteId != KErrNotFound) + { + return ETrue; + } + return EFalse; + } + +TBool CAknGlobalNoteSubject::IsAppsKeyLocked() + { + return iAppsKeyLocked; + } + +void CAknGlobalNoteSubject::SetAppsKeyLocked( TBool aLocked ) + { + if ( ( iAppsKeyLocked && aLocked ) || ( !iAppsKeyLocked && !aLocked ) ) + { + return; + } + + TInt err = ((CAknNotifierAppServerAppUi*)(CEikonEnv::Static())->EikAppUi())-> + SuppressAppSwitching( aLocked ); + + if ( !err ) + { + iAppsKeyLocked = aLocked; + } + } + +TInt CAknGlobalNoteSubject::EnableAutolockEmulation( TAny* aThis ) + { + CAknGlobalNoteSubject& me = *static_cast(aThis); + me.iKeyLockController->LockKeys(ETrue); + delete me.iIdle; + me.iIdle = 0; + return KErrNone; + } + + +TInt CAknGlobalNoteSubject::DisplayAlarmL( TInt aType, + const TDesC& aDescription, + const TDesC& /*aTime*/ ) + { + +#ifdef _DEBUG + RDebug::Print(_L("CAknGlobalNoteSubject::DisplayAlarmL type [%d], noteId [%d], priority [%d]"), + aType, iDisplayingNoteId, iCurrentPriority); +#endif + + TBuf buf; + + // Make sure that buffer will not overflow. + if ( aDescription.Length() > KGlobalNoteTextLength ) + { + buf.Append( aDescription.Left( KGlobalNoteTextLength ) ); + } + else + { + buf.Append( aDescription ); + } + + TInt rid( R_ALARM_CONTROL ); + TInt animation( 0 ); + TInt softkeys( 0 ); + TInt imageId( -1 ); + TInt maskId( -1 ); + + if ( aType & EMskOpen ) // msk + { + if ( aType & EHideSnooze ) // no snooze (+ no silence) + { + // stop_open_empty + softkeys = R_ALERT_SOFTKEYS_STOP_EMPTY__OPEN; + iAlarmData->iAlarmSoftkeys = EAknAlarmStopNone; + } + else if ( aType & ENoSilence ) // no silence + { + // stop_open_snooze + softkeys = R_ALERT_SOFTKEYS_STOP_SNOOZE__OPEN; + iAlarmData->iAlarmSoftkeys = EAknAlarmStopSnooze; + } + else // silence + { + // stop_open_silence + softkeys = R_ALERT_SOFTKEYS_STOP_SILENT__OPEN; + iAlarmData->iAlarmSoftkeys = EAknAlarmStopSilent; + } + } + else // no msk + { + if ( aType & EHideSnooze ) // no snooze (+ no silence) + { + // stop_empty_empty + softkeys = R_ALERT_SOFTKEYS_STOP_EMPTY__EMPTY; + iAlarmData->iAlarmSoftkeys = EAknAlarmStopNone; + } + else if ( aType & ENoSilence ) // no snooze + { + // stop_empty_snooze + softkeys = R_ALERT_SOFTKEYS_STOP_SNOOZE; + iAlarmData->iAlarmSoftkeys = EAknAlarmStopSnooze; + } + else // silence + { + // stop_empty_silence + softkeys = R_ALERT_SOFTKEYS_STOP_SILENT; + iAlarmData->iAlarmSoftkeys = EAknAlarmStopSilent; + } + } + + if ( aType & EClockAlarm ) + { + // animation = R_ANIM_CLOCK_ALARM; + imageId = EMbmAvkonQgn_note_alarm_clock; + maskId = EMbmAvkonQgn_note_alarm_clock_mask; + } + + else if ( aType & ECalendarAlarm ) + { + // animation = R_ANIM_CALENDAR_ALARM; + imageId = EMbmAvkonQgn_note_alarm_calendar; + maskId = EMbmAvkonQgn_note_alarm_calendar_mask; + } + else if ( aType == EAskWakeUp ) + { + animation = R_QGN_NOTE_QUERY_ANIM; + softkeys = R_AVKON_SOFTKEYS_YES_NO__YES; + } + + TInt noteId = + AddNoteToQueueL( rid, + buf, + KAlarmNotePriority, + CAknNoteDialog::ENoTimeout, + CAknNoteDialog::ENoTone, + -1, + imageId, + maskId, + animation, + softkeys ); + + CGlobalNoteInfo* alarmNoteInfo = (*iGlobalNoteList)[iGlobalNoteList->Count()-1]; + if ( alarmNoteInfo ) + { + alarmNoteInfo->iGlobalPopupPriority = KGlobalWindowPriority_Alarm; + alarmNoteInfo->iAlmFlag = aType; + } + + // We will not specify alarm otherwise here. Alarm implementation provides more precise + // information using AddAlarmAdditionalData. + CAknSDData* data = CAknSDData::NewL( + KAknSecondaryDisplayCategory, + aType == EAskWakeUp ? EAknSwitchOnAfterAlarmNote : EAknAlarmNote, + KNullDesC8 ); + + TBool sdDataSet = SetSDData( noteId, data ); + + if ( !sdDataSet ) // data ownership not transferred + { + delete data; + } + + TryDisplayNextNoteL(); + +#ifdef _DEBUG + RDebug::Print(_L("DisplayAlarmL noteId [%d], Display [%d], Prio [%d], AutoLock [%d], Limit [%d], Disabled [%d]"), + noteId, iDisplayingNoteId, iCurrentPriority, iAutoLock, iMaxDisplayPriorityLimit, iNotesDisabled); +#endif + + return noteId; + } + + +void CAknGlobalNoteSubject::AddAlarmAdditionalInfo( + TInt aType, + const TDesC& aTime, + const TDesC& aDate, + const TDesC& aSubject, + const TDesC& aLocation ) + { + if ( iAlarmData ) + { + iAlarmData->iType = aType > 0 ? + (SAknAlarmPSInfo::TAlarmType)aType : SAknAlarmPSInfo::EAknClock; + + iAlarmData->iTime.Zero(); + iAlarmData->iTime.Append( + aTime.Ptr(), + Min(iAlarmData->iTime.MaxLength(), + aTime.Length())); + + iAlarmData->iDate.Zero(); + iAlarmData->iDate.Append( + aDate.Ptr(), + Min(iAlarmData->iDate.MaxLength(), + aDate.Length())); + + iAlarmData->iSubject.Zero(); + iAlarmData->iSubject.Append( + aSubject.Ptr(), + Min(iAlarmData->iSubject.MaxLength(), + aSubject.Length())); + + iAlarmData->iLocation.Zero(); + iAlarmData->iLocation.Append( + aLocation.Ptr(), + Min(iAlarmData->iLocation.MaxLength(), + aLocation.Length())); + } + } + +TBool CAknGlobalNoteSubject::SetSDData( TInt aNoteId, CAknSDData* aData ) + { + TInt index = NoteIndex( aNoteId ); + + if ( index != KErrNotFound ) + { + delete (*iGlobalNoteList)[index]->iSDData; + (*iGlobalNoteList)[index]->iSDData = aData; + return ETrue; + } + + return EFalse; + } + +TBool CAknGlobalNoteSubject::IsPreallocatedNoteIdValid(const TInt aPreAllocatedNoteId) + { + if (aPreAllocatedNoteId) + { + // Pre-allocated note id is given. Check that it is from valid range and that there is no + // note with that id already existing. + if (aPreAllocatedNoteId >= iNoteId || NoteIndex(aPreAllocatedNoteId) != KErrNotFound) + { + return EFalse; + } + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::AutolockStatusNotificationL +// ----------------------------------------------------------------------------- +// +TInt CAknGlobalNoteSubject::AutolockStatusNotificationL(TAny* aObj) + { + if (aObj != NULL) + { + static_cast(aObj)->HandleAutolockStatusNotificationL(); + return KErrNone; + } + else + { + return KErrArgument; + } + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::HandleAutolockStatusNotificationL +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::HandleAutolockStatusNotificationL() + { + iAutolockStatusProperty.Get(iAutoLock); + + iGlobalNote->SetAutoLock(iAutoLock > EAutolockOff); + if (iAutoLock > EAutolockOff) + { + if (iIdle) + { + return; // Notify already activated. + } + else + { + iIdle = CIdle::NewL(CActive::EPriorityIdle); + iIdle->Start(TCallBack(EnableAutolockEmulation, this)); + } + } + else + { + if (iIdle) // Cancel enabling autolock. + { + delete iIdle; + iIdle = 0; + } + } + +#ifdef _DEBUG + _LIT(KDmsg,"AknGlobalNote (HandleAutolockStatusNotificationL), AutolockStatus: %d"); + RDebug::Print(KDmsg, iAutoLock); +#endif + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CSubscriber::CSubscriber +// ----------------------------------------------------------------------------- +// +CAknGlobalNoteSubject::CSubscriber::CSubscriber(TCallBack aCallBack, RProperty& aProperty) + : CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty) + { + CActiveScheduler::Add(this); + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CSubscriber::~CSubscriber +// ----------------------------------------------------------------------------- +// +CAknGlobalNoteSubject::CSubscriber::~CSubscriber() + { + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CSubscriber::Subscribe +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::CSubscriber::Subscribe() + { + if (!IsActive()) + { + iProperty.Subscribe(iStatus); + SetActive(); + } + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CSubscriber::StopSubscribe +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::CSubscriber::StopSubscribe() + { + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CSubscriber::RunL +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::CSubscriber::RunL() + { + if (iStatus.Int() == KErrNone) + { + iCallBack.CallBack(); + Subscribe(); + } + } + +// ----------------------------------------------------------------------------- +// CAknGlobalNoteSubject::CSubscriber::DoCancel +// ----------------------------------------------------------------------------- +// +void CAknGlobalNoteSubject::CSubscriber::DoCancel() + { + iProperty.Cancel(); + } + +// End of File