bluetoothengine/btnotif/src/BTNotifier.cpp
branchRCL_3
changeset 24 269724087bed
parent 23 9386f31cc85b
--- a/bluetoothengine/btnotif/src/BTNotifier.cpp	Wed Sep 01 12:20:04 2010 +0100
+++ b/bluetoothengine/btnotif/src/BTNotifier.cpp	Tue Sep 14 21:37:10 2010 +0300
@@ -93,6 +93,10 @@
     iBTEngSettings = CBTEngSettings::NewL();
     iDevMan = CBTEngDevMan::NewL( this );
     iNotifUiUtil = CBTNotifUIUtil::NewL( iIsCoverUI );
+    iAuthoriseDialog = CBTNotifUIUtil::NewL( iIsCoverUI );
+
+    TCallBack processParamsCb(ProcessStartParamsCallBack, this);
+    iProcessStartParamsCallBack = new (ELeave) CAsyncCallBack(processParamsCb, CActive::EPriorityHigh);
     }
 
 // ----------------------------------------------------------
@@ -103,6 +107,8 @@
     {
     FLOG(_L("[BTNOTIF]\t CBTNotifierBase::~CBTNotifierBase()"));    
     Cancel();
+
+    delete iProcessStartParamsCallBack;
     FLOG(_L("[BTNOTIF]\t CBTNotifierBase::~CBTNotifierBase() -- Done"));    
     }
 
@@ -145,16 +151,31 @@
 //
 void CBTNotifierBase::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
     {
+    if (!iMessage.IsNull())
+        {
+        // We're already active. The notifier server will complete the message if we leave.
+        User::Leave(KErrInUse);
+        }
+
+    __ASSERT_DEBUG(!iParamBuffer, BTNOTIF_PANIC(EiParamBufferLeakedFromPreviousActivation));
+
     if( !iNotifUiUtil )
         {
         iNotifUiUtil = CBTNotifUIUtil::NewL( iIsCoverUI );    
         }
-    
-    TRAPD(err, GetParamsL(aBuffer, aReplySlot, aMessage));
-    if (err)
+    if( !iAuthoriseDialog )
         {
-        CompleteMessage(err);
+        iNotifUiUtil = CBTNotifUIUtil::NewL( iIsCoverUI );    
         }
+
+    iParamBuffer    = aBuffer.AllocL(); // ProcessStartParamsCallBack responsible for deallocation
+    iMessage        = aMessage;
+    iReplySlot      = aReplySlot;
+
+    // Return from StartL as soon as possible - processing the parameters involves displaying
+    // waiting dialogs which would block the notifier server thus preventing other notifiers
+    // from running, were we to do it from here.
+    iProcessStartParamsCallBack->CallBack();
     }
 
 // ----------------------------------------------------------
@@ -166,9 +187,23 @@
     {
     FLOG(_L("[BTNOTIF]\t CBTNotifierBase::Cancel()"));    
 
+    // In case we are being called before ProcessStartParamsCallBack
+    // had a chance to run:
+    delete iParamBuffer;
+    iParamBuffer = NULL;
+
+    if (iProcessStartParamsCallBack)
+        {
+        iProcessStartParamsCallBack->Cancel();
+        // - the callback object is deleted in the destructor.
+        }
+
     delete iNotifUiUtil;
     iNotifUiUtil = NULL;
     
+    delete iAuthoriseDialog;
+    iAuthoriseDialog = NULL;
+    
 	delete iBTEngSettings;
     iBTEngSettings = NULL;
 
@@ -199,6 +234,25 @@
     return (ret);
     }
 
+TInt CBTNotifierBase::ProcessStartParamsCallBack(TAny* aNotif)
+    {
+    CBTNotifierBase* notif = static_cast<CBTNotifierBase*>(aNotif);
+
+    __ASSERT_DEBUG(notif->iParamBuffer, BTNOTIF_PANIC(EiParamBufferNullInProcessStartParams));
+    __ASSERT_DEBUG(!notif->iMessage.IsNull(), BTNOTIF_PANIC(EiMessageNullInProcessStartParams));
+
+    TRAPD(err, notif->ProcessStartParamsL());
+    if (err)
+        {
+        notif->CompleteMessage(err);
+        }
+
+    delete notif->iParamBuffer;
+    notif->iParamBuffer = NULL;
+
+    return 0;
+    }
+
 
 // ----------------------------------------------------------
 // CBTNotifierBase::AutoLockOnL