--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AknGlobalUI/NotifierWrapper/src/AknNotifierWrapper.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,702 @@
+/*
+* Copyright (c) 2004-2007 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: Notifier server app wrapper implementation.
+*
+*/
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uiklaf/private/pluginuid.hrh>
+#include <uikon/eiknotifyalert.h>
+#endif
+#include <apgtask.h>
+#include <apgcli.h>
+#include <apacmdln.h>
+#include <coemain.h>
+#include <uikon/eiksrvui.h>
+#include "AknNotifierWrapper.h"
+#include "AknNotifierControllerUtilities.h"
+#include <AknNotifierControllerPlugin.h>
+#include <AknCapServerDefs.h>
+
+const TInt KPreLoadEnabledButNotDoneYet(2);
+
+//-------------------------------------------
+// CAknNotifierMessageObserver
+//-------------------------------------------
+
+CAknNotifierMessageObserver::CAknNotifierMessageObserver(TUid aNotifierUid,
+ MAknNotifierWrapper* aOwner,
+ const RMessagePtr2& aClientMessage,
+ TInt aReplySlot)
+:CActive(CActive::EPriorityStandard),
+ iNotifierUid(aNotifierUid),
+ iReplySlot(aReplySlot),
+ iOwner(aOwner)
+ {
+ iMessage = aClientMessage;
+ CActiveScheduler::Add(this);
+ }
+
+
+EXPORT_C CAknNotifierMessageObserver* CAknNotifierMessageObserver::NewServerRequestL(
+ TUid aNotifierUid,
+ MAknNotifierWrapper* aOwner,
+ const RMessagePtr2& aClientMessage,
+ TInt aReplySlot)
+ {
+ CAknNotifierMessageObserver* me =
+ new (ELeave) CAknNotifierMessageObserver(aNotifierUid,aOwner,aClientMessage,aReplySlot);
+
+ // a bit awkward I admit...
+ if (!aClientMessage.IsNull())
+ {
+ CleanupStack::PushL(me);
+ me->iReplyBuf = HBufC8::NewL(aClientMessage.GetDesLength(aReplySlot));
+ // we need ptr which keeps its address during async operation
+ me->iReplyDesc = new (ELeave) TPtr8(me->iReplyBuf->Des());
+ CleanupStack::Pop();
+
+ // just in case: if notifier implementation wants to transmit data via replybuf for
+ // some reason
+ aClientMessage.Read(aReplySlot,*(me->iReplyDesc));
+ }
+
+ return me;
+ }
+
+
+CAknNotifierMessageObserver::~CAknNotifierMessageObserver()
+ {
+ delete iReplyDesc;
+ delete iReplyBuf;
+ delete iInputBuf;
+ __ASSERT_DEBUG(!IsActive(), User::Invariant() );
+ }
+
+void CAknNotifierMessageObserver::DoCancel()
+ {
+ if (iOwner)
+ {
+ iOwner->AsyncMessageCompleted( this );
+ }
+
+ if (!iMessage.IsNull())
+ {
+ iMessage.Complete(KErrCancel);
+ }
+
+ User::WaitForRequest(iStatus);
+ delete this;
+ }
+
+void CAknNotifierMessageObserver::RunL()
+ {
+ if (iOwner)
+ {// offer message from app-server for wrapper to clone
+ iOwner->AsyncMessageCompleted( this );
+ }
+
+ // if Owner did not complete the message, do default reply
+ if (!iMessage.IsNull())
+ {
+ TInt err = iMessage.Write(iReplySlot,iReplyBuf->Des());
+ iMessage.Complete(err?err:iStatus.Int());
+ }
+ delete this;
+ }
+
+//-------------------------------------------
+// MAknNotifierWrapper
+//-------------------------------------------
+
+// Default implementation to avoid SC break.
+EXPORT_C void MAknNotifierWrapper::UpdateNotifierL(
+ TUid /*aNotifierUid*/,
+ const TDesC8& /*aBuffer*/,
+ TInt /*aReplySlot*/,
+ const RMessagePtr2& /*aMessage*/ )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+//-------------------------------------------
+// CAknNotifierWrapperLight
+//-------------------------------------------
+EXPORT_C CAknNotifierWrapperLight::~CAknNotifierWrapperLight()
+ {
+ }
+
+EXPORT_C CAknNotifierWrapperLight::CAknNotifierWrapperLight(
+ MAknNotifierWrapper& aSessionOwningNotifier,
+ TUid aNotifierUid,
+ TUid aChannel,
+ TInt aPriority )
+:iOwner(aSessionOwningNotifier)
+ {
+ iInfo.iUid = aNotifierUid;
+ iInfo.iChannel = aChannel;
+ iInfo.iPriority = aPriority;
+ }
+
+
+EXPORT_C TPtrC8 CAknNotifierWrapperLight::UpdateL(const TDesC8& aBuffer)
+ {
+ return iOwner.UpdateNotifierL( iInfo.iUid, aBuffer );
+ }
+
+EXPORT_C void CAknNotifierWrapperLight::UpdateL(const TDesC8& aBuffer, TInt aReplySlot,
+ const RMessagePtr2& aMessage)
+ {
+ iOwner.UpdateNotifierL( iInfo.iUid, aBuffer, aReplySlot, aMessage );
+ }
+
+EXPORT_C void CAknNotifierWrapperLight::Cancel()
+ {
+ iOwner.CancelNotifier(iInfo.iUid);
+ }
+
+EXPORT_C void CAknNotifierWrapperLight::StartL(const TDesC8& aBuffer, TInt aReplySlot,
+ const RMessagePtr2& aMessage)
+ {
+ iOwner.StartNotifierL(iInfo.iUid, aBuffer, aReplySlot, aMessage);
+ }
+
+EXPORT_C TPtrC8 CAknNotifierWrapperLight::StartL(const TDesC8& aBuffer)
+ {
+ return iOwner.StartNotifierL(iInfo.iUid, aBuffer);
+ }
+
+EXPORT_C MEikSrvNotifierBase2::TNotifierInfo CAknNotifierWrapperLight::Info() const
+ {
+ return iInfo;
+ }
+
+EXPORT_C MEikSrvNotifierBase2::TNotifierInfo CAknNotifierWrapperLight::RegisterL()
+ {
+ return iInfo;
+ }
+
+EXPORT_C void CAknNotifierWrapperLight::Release()
+ {
+ Cancel();
+ delete this;
+ }
+
+EXPORT_C TInt CAknNotifierWrapperLight::NotifierCapabilites()
+ {
+ return MEikSrvNotifierBase2::NotifierCapabilites();
+ }
+
+//-------------------------------------------
+// CAknNotifierWrapper
+//-------------------------------------------
+
+EXPORT_C CAknNotifierWrapper::CAknNotifierWrapper(TUid aNotifierUid, TUid aChannel, TInt aPriority)
+ :CAknNotifierWrapperLight(*this, aNotifierUid, aChannel, aPriority)
+ {
+ iClient.SetServerAppUid(AppServerUid());
+ }
+
+CAknNotifierWrapper::CAknNotifierWrapper(TUid aNotifierUid, TUid aChannel, TInt aPriority,
+ TUid aAppServerUid)
+:CAknNotifierWrapperLight(*this, aNotifierUid, aChannel, aPriority), iAppServerUid(aAppServerUid)
+ {
+ iClient.SetServerAppUid(iAppServerUid);
+ }
+
+
+EXPORT_C CAknNotifierWrapper::~CAknNotifierWrapper()
+ {
+ CEikServAppUi* appUi = (CEikServAppUi*)CCoeEnv::Static()->AppUi();
+ if (appUi && appUi->NotifierController())
+ {
+ appUi->NotifierController()->RegisterNotifierControllerPlugin(this, ETrue);
+ }
+
+ delete iReplyBuffer;
+
+ // Make sure that there are no pending messages
+ __ASSERT_DEBUG(iMessageQueue.Count()==0, User::Invariant());
+
+ iClient.Close();
+ }
+
+// We use CEikServAppUi idle queue to launch application servers (applications will be started after
+// eiksrv-construction has been completed )
+EXPORT_C MEikSrvNotifierBase2::TNotifierInfo CAknNotifierWrapper::RegisterL()
+ {
+ CEikServAppUi* appUi = (CEikServAppUi*)CCoeEnv::Static()->AppUi();
+ if (appUi)
+ {
+ if (AppServerUid()!=KAknCapServerUid) // aknCapServer is handled elsewhere
+ {
+ appUi->StartNewServerApplicationL(AppServerUid());
+ }
+
+ appUi->NotifierController()->RegisterNotifierControllerPlugin(this, EFalse);
+ }
+ return CAknNotifierWrapperLight::RegisterL();
+ }
+
+
+EXPORT_C TPtrC8 CAknNotifierWrapper::UpdateNotifierL( TUid aNotifierUid, const TDesC8& aBuffer)
+ {
+ User::LeaveIfError(iClient.SendSync(EUpdateNotifier, aNotifierUid, aBuffer,
+ SynchronousReplyBuf(), KNullDesC));
+
+ return TPtrC8(SynchronousReplyBuf());
+ }
+
+EXPORT_C void CAknNotifierWrapper::UpdateNotifierL( TUid aNotifierUid, const TDesC8& aBuffer,
+ TInt aReplySlot, const RMessagePtr2& aMessage)
+ {
+ CAknNotifierMessageObserver* entry =
+ CreateNewQueueEntryL(aNotifierUid, aBuffer, aReplySlot, aMessage);
+
+ if (entry)
+ {
+ iClient.SendAsync(EUpdateNotifierAndGetResponse, aNotifierUid,*entry->iInputBuf, entry,
+ KNullDesC);
+ }
+ }
+
+void CAknNotifierWrapper::CompleteOutstandingRequests( TUid aNotifierUid, TInt aReason )
+ {
+ for ( TInt i = 0; i < iMessageQueue.Count(); i++ )
+ {
+ if (iMessageQueue[i]->iNotifierUid == aNotifierUid)
+ {
+ // This leaves listener to active state, it will be destroyed when a message in
+ // Notifier server application is completed.
+ // Effectively this means that plugin can't send any data inside message which is
+ // being cancelled.
+ if (!iMessageQueue[i]->iMessage.IsNull())
+ {
+ iMessageQueue[i]->iMessage.Complete(aReason);
+ }
+ }
+ }
+ }
+
+EXPORT_C void CAknNotifierWrapper::CancelNotifier( TUid aNotifierUid )
+ {
+ iClient.SendSync(ECancelNotifier, aNotifierUid, KNullDesC8, SynchronousReplyBuf(), KNullDesC);
+ CompleteOutstandingRequests( aNotifierUid, KErrCancel);
+ }
+
+
+CAknNotifierMessageObserver* CAknNotifierWrapper::CreateNewQueueEntryL(TUid aNotifierUid,
+ const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
+ {
+ CAknNotifierMessageObserver* entry = 0;
+ if (!aMessage.IsNull())
+ {
+ entry = CAknNotifierMessageObserver::NewServerRequestL(aNotifierUid, this, aMessage,
+ aReplySlot);
+
+ CleanupStack::PushL(entry);
+ entry->iInputBuf = aBuffer.AllocL();
+ CleanupStack::Pop();
+ TInt err = iMessageQueue.Append(entry);
+ if (err)
+ { // completes client message with err;
+ TRequestStatus* ptr = &entry->iStatus;
+ User::RequestComplete(ptr, err);
+ entry = 0;
+ }
+ }
+ return entry;
+ }
+
+EXPORT_C void CAknNotifierWrapper::StartNotifierL( TUid aNotifierUid, const TDesC8& aBuffer,
+ TInt aReplySlot, const RMessagePtr2& aMessage)
+ {
+ CAknNotifierMessageObserver* entry =
+ CreateNewQueueEntryL(aNotifierUid, aBuffer, aReplySlot, aMessage);
+
+ if (entry)
+ {
+ iClient.SendAsync(
+ EStartNotifierAndGetResponse,
+ aNotifierUid,
+ *entry->iInputBuf,
+ entry,
+ KNullDesC);
+ }
+ }
+
+EXPORT_C TPtrC8 CAknNotifierWrapper::StartNotifierL( TUid aNotifierUid, const TDesC8& aBuffer)
+ {
+ User::LeaveIfError(iClient.SendSync(EStartNotifier, aNotifierUid, aBuffer,
+ SynchronousReplyBuf(), KNullDesC));
+
+ return TPtrC8(SynchronousReplyBuf());
+ }
+
+// Just remove completed entry from queue, default completion (ie. just copying message from
+// app server) is currently enough for us.
+EXPORT_C void CAknNotifierWrapper::AsyncMessageCompleted( CAknNotifierMessageObserver* aEntry )
+ {
+ TInt status = aEntry->iStatus.Int();
+
+ TInt index = iMessageQueue.Find(aEntry);
+ if (index != KErrNotFound)
+ {
+ iMessageQueue.Remove(index);
+ }
+
+ if ( status == KErrServerTerminated && AppServerUid() != KCommonNotifierAppSrvUid)
+ { // Just try to restart (connect on next request), not interested if success or fail
+ //
+ // We could clone the original message here and resend it to server
+ // if information was really vital for system
+ Client().Close();
+ Client().SetHandle(0);
+
+ TRAP_IGNORE(((CEikServAppUi*)CCoeEnv::Static()->AppUi())->StartNewServerApplicationL(
+ AppServerUid()));
+ }
+ }
+
+EXPORT_C CAknNotifierWrapper* CAknNotifierWrapper::NewL(
+ TUid aNotifierUid,
+ TUid aChannel,
+ TInt aPriority,
+ TUid aAppServerUid,
+ TUint aReplyBufSize)
+ {
+ CAknNotifierWrapper* me =
+ new (ELeave) CAknNotifierWrapper(aNotifierUid, aChannel, aPriority, aAppServerUid);
+
+ CleanupStack::PushL(me);
+ me->ConstructL(aReplyBufSize);
+ CleanupStack::Pop();
+ return me;
+ }
+
+EXPORT_C void CAknNotifierWrapper::DoNotifierControllerCommand(TInt aCommand)
+ {
+ iClient.SendAsync(aCommand);
+ }
+
+void CAknNotifierWrapper::ConstructL(TUint aReplyBufSize)
+ {
+ iReplyBuffer = HBufC8::NewL(aReplyBufSize);
+ }
+
+RAknNotifierAppServClient::RAknNotifierAppServClient()
+ :iAppServerUid(KNullUid), iOwnerUsingMonitor(0)
+ {
+ }
+
+void RAknNotifierAppServClient::SetServerAppUid(TUid aAppServerUid)
+ {
+ iAppServerUid = aAppServerUid;
+ }
+
+TInt RAknNotifierAppServClient::StartServer()
+ {
+ TRAPD(ret, StartServerL())
+ return ret;
+ }
+
+void RAknNotifierAppServClient::StartServerL()
+ {
+ if (Handle() != 0)
+ {
+ return;
+ }
+
+ if (iAppServerUid == KNullUid)
+ {
+ User::Leave(KErrGeneral);
+ }
+
+ _LIT(KServerNameFormat, "%08x_%08x_AppServer");
+ TFullName serverName;
+ serverName.Format(KServerNameFormat, KUikonUidPluginInterfaceNotifiers, iAppServerUid);
+ TFindServer find(serverName);
+ TFullName fullName;
+ if (find.Next(fullName) == KErrNone)
+ {
+ ConnectExistingByNameL(serverName);
+ if (iOwnerUsingMonitor)
+ {
+ iOwnerUsingMonitor->AppServerConnectedL();
+ }
+ return;
+ }
+
+ User::Leave(KErrNotReady);
+ }
+
+TUid RAknNotifierAppServClient::ServiceUid() const
+ {
+ return KAknNotifierServiceUid;
+ }
+
+TInt RAknNotifierAppServClient::SendSync(TNotifierMessage aFunction, TUid aNotifierUid,
+ const TDesC8& aBuffer, TPtr8 aReply, const TDesC& aLibraryName)
+ {
+ // just an optimisation
+ if (aFunction == ECancelNotifier && !Handle())
+ {
+ return KErrNone;
+ }
+
+ TInt err = StartServer();
+ return err ? err : SendReceive(aFunction, TIpcArgs((TInt)aNotifierUid.iUid, &aBuffer, &aReply,
+ &aLibraryName));
+ }
+
+void RAknNotifierAppServClient::SendAsync(TNotifierMessage aFunction, TUid aNotifierUid,
+ const TDesC8& aBuffer, CAknNotifierMessageObserver* aQueueEntry, const TDesC& aLibraryName)
+ {
+ TInt err = StartServer();
+
+ aQueueEntry->Start();
+ if (err)
+ {
+ TRequestStatus* sptr= &aQueueEntry->iStatus;
+ User::RequestComplete(sptr, err);
+ return;
+ }
+ // we implicitely trust that aLibraryName will exist when data is extracted at other end...
+ SendReceive(
+ aFunction,
+ TIpcArgs((TInt)aNotifierUid.iUid, &aBuffer, aQueueEntry->iReplyDesc, &aLibraryName),
+ aQueueEntry->iStatus);
+ }
+
+TInt RAknNotifierAppServClient::SendAsync(TInt aNotifierControllerCommand)
+ {
+ if (Handle()!=0)
+ {
+ return Send(KDoNotifierControllerCommand, TIpcArgs(aNotifierControllerCommand));
+ }
+
+ // omit error as there is no need to forward commands to server apps which are not running yet.
+ return KErrNone;
+ }
+
+EXPORT_C CAknCommonNotifierWrapper* CAknCommonNotifierWrapper::NewL(
+ TUid aNotifierUid,
+ TUid aChannel,
+ TInt aPriority,
+ const TDesC& aLibraryName,
+ TUint aReplyBufSize,
+ TBool aPreLoad)
+ {
+ CAknCommonNotifierWrapper* me =
+ new (ELeave) CAknCommonNotifierWrapper(aNotifierUid, aChannel, aPriority, aPreLoad);
+
+ CleanupStack::PushL(me);
+ me->ConstructL(aLibraryName, aReplyBufSize);
+ CleanupStack::Pop();
+ return me;
+ }
+
+void CAknCommonNotifierWrapper::ConstructL(const TDesC& aLibraryName, TUint aReplyBufSize)
+ {
+ SetSynchReplybuf(HBufC8::NewL(aReplyBufSize));
+ iLibraryName = aLibraryName.AllocL();
+ Client().SetOwnerUsingMonitor(this);
+ }
+
+CAknCommonNotifierWrapper::CAknCommonNotifierWrapper(
+ TUid aNotifierUid,
+ TUid aChannel,
+ TInt aPriority,
+ TBool aPreLoad)
+:CAknNotifierWrapper(aNotifierUid, aChannel, aPriority), iPreLoad(aPreLoad)
+ {
+ Client().SetServerAppUid(AppServerUid());
+ if (aPreLoad)
+ {
+ iPreLoad = KPreLoadEnabledButNotDoneYet;
+ }
+ }
+
+EXPORT_C void CAknCommonNotifierWrapper::SetCustomSecurityHandler(
+ MAknNotifierCustomSecurityCheck* aHandler)
+ {
+ iCustomSecurityCheck = aHandler;
+ }
+
+CAknCommonNotifierWrapper::~CAknCommonNotifierWrapper()
+ {
+ delete iMonitor;
+ delete iIdle;
+ if (iCustomSecurityCheck)
+ {
+ iCustomSecurityCheck->Release();
+ }
+ delete iLibraryName;
+ iPendingArray.Close();
+ }
+
+void CAknCommonNotifierWrapper::StartNotifierL( TUid aNotifierUid, const TDesC8& aBuffer,
+ TInt aReplySlot, const RMessagePtr2& aMessage)
+ {
+ if (iPreLoad == KPreLoadEnabledButNotDoneYet) // only preload libs to support message queue
+ {
+ iPendingArray.AppendL(TPendingMsg(aNotifierUid, aMessage));
+ return;
+ }
+
+ if (iCustomSecurityCheck)
+ {
+ iCustomSecurityCheck->CustomSecurityCheckL(aMessage);
+ }
+
+ CAknNotifierMessageObserver* entry =
+ CreateNewQueueEntryL(aNotifierUid, aBuffer, aReplySlot, aMessage);
+
+ if (entry)
+ {
+ Client().SendAsync(
+ EStartNotifierAndGetResponse,
+ aNotifierUid,
+ *entry->iInputBuf,
+ entry,
+ *iLibraryName);
+ }
+ }
+
+TPtrC8 CAknCommonNotifierWrapper::StartNotifierL( TUid aNotifierUid, const TDesC8& aBuffer)
+ {
+ if (iPreLoad == KPreLoadEnabledButNotDoneYet)
+ {
+ // In case of synchronous commands (start / update) we cannot delay sending messages,
+ // only way to recover is to return error. Update cannot occur before one successfull
+ // start so it does need changes.
+ User::Leave(KErrNotReady);
+ }
+
+ User::LeaveIfError(Client().SendSync(EStartNotifier, aNotifierUid, aBuffer,
+ SynchronousReplyBuf(), *iLibraryName));
+
+ return TPtrC8(SynchronousReplyBuf());
+ }
+
+TBool CallBackLoad(TAny* aThis)
+ {
+ return ((CAknCommonNotifierWrapper*)aThis)->PreLoadLibrary();
+ }
+
+EXPORT_C void CAknCommonNotifierWrapper::PreLoadLibraryL()
+ {
+ iPreLoad = ETrue; // restore original, real boolean value once callback from server arrives
+ if (!iIdle)
+ {
+ iIdle = CIdle::NewL(CActive::EPriorityIdle);
+ iIdle->Start(TCallBack(CallBackLoad, this));
+ }
+ }
+
+// On succes this method will cause unbalanced reference count in app server -> library will not be
+// unloaded unless server terminates.
+TBool CAknCommonNotifierWrapper::PreLoadLibrary()
+ {
+ TInt err = Client().SendSync(
+ (TNotifierMessage)EAknNfySrvLoadLibrary,
+ KNullUid,
+ KNullDesC8,
+ SynchronousReplyBuf(),
+ *iLibraryName);
+
+ if (err == KErrNotReady)
+ {
+ return ETrue;
+ }
+ else
+ {
+ delete iIdle;
+ iIdle = 0;
+ return EFalse;
+ }
+ }
+
+MEikSrvNotifierBase2::TNotifierInfo CAknCommonNotifierWrapper::RegisterL()
+ {
+ if (iPreLoad)
+ {
+ CEikServAppUi* appUi = (CEikServAppUi*)CCoeEnv::Static()->AppUi();
+ if (appUi)
+ {
+ appUi->NotifierController()->RegisterPreloadPluginL(this);
+ }
+ }
+ return CAknNotifierWrapper::RegisterL();
+ }
+
+
+void CAknCommonNotifierWrapper::HandleServerAppExit(TInt)
+ {
+ delete iMonitor;
+ iMonitor = 0;
+ Client().Close();
+ Client().SetHandle(0);
+ if (iPreLoad)
+ {
+ iPreLoad = KPreLoadEnabledButNotDoneYet;
+ }
+ }
+
+void CAknCommonNotifierWrapper::CancelNotifier( TUid aNotifierUid )
+ {
+ // if there are pending requests, there cannot be actual connection to server yet
+ if (iPendingArray.Count())
+ {
+ for (TInt i = iPendingArray.Count()-1; i >= 0; i--)
+ {
+ if (iPendingArray[i].iUid == aNotifierUid.iUid)
+ {
+ iPendingArray.Remove(i);
+ }
+ }
+ }
+ else
+ {
+ CAknNotifierWrapper::CancelNotifier( aNotifierUid );
+ }
+ }
+
+void TryProcessPendingEntryL(CAknCommonNotifierWrapper::TPendingMsg& aPendingEntry,
+ CAknCommonNotifierWrapper* aThis)
+ {
+ HBufC8* buf = HBufC8::NewLC(aPendingEntry.iMessage.GetDesLengthL(1));
+ TPtr8 ptr = buf->Des();
+ aPendingEntry.iMessage.ReadL(1, ptr );
+ aThis->StartNotifierL(TUid::Uid(aPendingEntry.iUid), *buf, 2, aPendingEntry.iMessage );
+ CleanupStack::PopAndDestroy();
+ }
+
+void CAknCommonNotifierWrapper::AppServerConnectedL()
+ {
+ if (!iMonitor)
+ {
+ iMonitor = CApaServerAppExitMonitor::NewL(Client(), *this, CActive::EPriorityStandard);
+ }
+
+ for (TInt i = 0; i < iPendingArray.Count(); i++)
+ { // common app servers have no problem with asynch message slots
+ // anyway, we don't allow pending messages to abort StartServerL so trap needed
+ TRAP_IGNORE(TryProcessPendingEntryL(iPendingArray[i], this));
+ }
+
+ iPendingArray.Reset();
+ }
+
+// End of file