bluetoothengine/bteng/bttoggle/src/bttoggle.cpp
changeset 0 f63038272f30
child 1 6a1fe72036e3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bteng/bttoggle/src/bttoggle.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,366 @@
+/*
+* Copyright (c) 2009 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:  Bluetooth Toggle application is being used by Telephony for 
+ *  							switching on/off Bluetooth when a long key press of asterisk 
+ *  							is detected 
+ *
+*/
+
+
+
+//  Include Files  
+#include "bttoggle.h"
+#include "btengprivatecrkeys.h"
+#include "btengsrvbbconnectionmgr.h"
+#include "debug.h"
+
+#include <e32base.h>
+#include <e32std.h>
+
+void Panic(TBTTogglePanic aPanic)
+  {
+  User::Panic(KBTTogglePanicCat, aPanic);
+  }
+
+LOCAL_C void DoStartL()
+  {
+  //Create active scheduler (to run active objects)
+  CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+  CleanupStack::PushL (scheduler );
+  CActiveScheduler::Install (scheduler );
+
+  CBTToggle* bttoggle = CBTToggle::NewL();			
+  bttoggle->ToggleBT();
+
+  CActiveScheduler::Start();
+
+  delete bttoggle; 		
+  CleanupStack::PopAndDestroy (scheduler );
+  return; 
+  }
+
+//  Global Functions
+GLDEF_C TInt E32Main()
+  {	 	
+  CTrapCleanup* cleanup = CTrapCleanup::New();	
+
+  // Run application code inside TRAP harness		
+  TRAPD(mainError, DoStartL());
+  if (mainError)
+    {
+    TRACE_INFO((_L("[BTENG][BTTOGGLE]DoStartL error: %d" ), mainError))
+    }
+  delete cleanup;		
+  return KErrNone;
+  }
+
+// ==========================================================
+// CBTToggle::CBTToggle()
+// Constructor
+// ==========================================================
+//
+CBTToggle::CBTToggle() : CActive(EPriorityStandard)
+		    {		
+		    }
+
+// ==========================================================
+// CBTToggle::~CBTToggle()
+// Destructor
+// ==========================================================
+//
+CBTToggle::~CBTToggle()
+  {
+  TRACE_FUNC_ENTRY
+
+  Cancel(); 		
+  delete iSettings; 	
+  iNotifier.Close();		
+  iLinkCountProperty.Close();
+
+  TRACE_FUNC_EXIT
+  }
+
+// ==========================================================
+// CBTToggle::ConstructL
+// 
+// ==========================================================
+//
+void CBTToggle::ConstructL()
+  {
+  TRACE_FUNC_ENTRY		
+  iSettings = CBTEngSettings::NewL(NULL);	
+  CActiveScheduler::Add(this); 	
+  iActiveNotifier = ENoneQuery; 
+  TInt errConnect = iNotifier.Connect();	
+  if (errConnect)
+    {
+    TRACE_INFO((_L("[BTENG][BTTOGGLE] iNotifier connect fail: %d" ), errConnect))
+    User::Leave(errConnect);
+    }				
+  User::LeaveIfError( iLinkCountProperty.Attach( KPropertyUidBluetoothCategory, 
+      KPropertyKeyBluetoothGetPHYCount ) );	  
+  TRACE_FUNC_EXIT
+  }
+
+// ==========================================================
+// CBTToggle::NewL
+//
+// ==========================================================
+//
+CBTToggle* CBTToggle::NewL()
+  {
+  TRACE_FUNC_ENTRY
+  CBTToggle* self = new ( ELeave ) CBTToggle();
+  CleanupStack::PushL(self);  
+  self->ConstructL();
+  CleanupStack::Pop(self);
+  TRACE_FUNC_EXIT
+  return self; 
+  }
+
+// ==========================================================
+// CBTToggle::ToggleBT
+// Toggles Bluetooth on or off and shows dialog 
+// (if the BT is switched for the first time after flashing)
+// and notification
+// ==========================================================
+//
+void CBTToggle::ToggleBT()
+  {
+  TRACE_FUNC_ENTRY	
+
+  TBTPowerStateValue state;	
+  iSettings->GetPowerState(state);	  
+
+  //BT off
+  if (EBTPowerOff == state)
+    {					
+    TBool isInOffline = CheckOfflineMode(); 
+    if (isInOffline) //Offline mode
+      {					
+      TRACE_INFO((_L("[BTENG][BTTOGGLE]Offline mode") ))
+      SwitchBtOnWithPowerNotif(); 						
+      }
+    else //other than offline
+      {									
+      TBuf<KHCILocalDeviceNameMaxLength> localName;
+      iSettings->GetLocalName(localName);														
+
+      //There is no BT local name defined		
+      if (0 >= localName.Length()) 
+        {																
+        SwitchBtOnWithPowerNotif(); 
+        }
+      else //BT name already defined
+        {				
+        ChangeBtPowerMode(EBTPowerOn);
+        }				
+      } 		
+    } 	
+  else //BT on 
+    {				
+    TInt linkCount = 0; 
+    TInt errLinkCount = iLinkCountProperty.Get( linkCount );		
+    TRACE_INFO((_L("[BTENG][BTTOGGLE] linkCount: %d error: %d" ), linkCount, errLinkCount))		
+
+    //BT Connected or error obtaining link count (in the case of error, we are cautious and assume BT is connected)
+    if (errLinkCount || linkCount > 0)
+      {
+      TRACE_INFO((_L("[BTENG][BTTOGGLE]Ongoing BT connection") ))								
+      __ASSERT_DEBUG(iActiveNotifier == ENoneQuery, Panic(EBTToggleInvalidStateCloseConnectionQuery));
+
+      iActiveNotifier = ECloseConnectionQuery;						
+      iPckgGenericQuery().iMessageType = EBTSwitchOffAnyway;
+      iPckgGenericQuery().iNameExists = EFalse;
+      iNotifier.StartNotifierAndGetResponse(iStatus, KBTGenericQueryNotifierUid, iPckgGenericQuery, iConnQuery );			
+      SetActive();															
+      }	
+    //No open connections
+    else
+      {
+      TRACE_INFO((_L("[BTENG][BTTOGGLE] No BT connections") ))
+      ChangeBtPowerMode(EBTPowerOff);
+      }					 
+    }
+  TRACE_FUNC_EXIT	
+  }
+
+// ==========================================================
+// CBTToggle::CheckOfflineMode
+// Checks whether current profile is Offline  
+// ==========================================================
+//
+TBool CBTToggle::CheckOfflineMode()
+  {
+  TRACE_FUNC_ENTRY
+  TCoreAppUIsNetworkConnectionAllowed offline = ECoreAppUIsNetworkConnectionAllowed;  
+  TBTEnabledInOfflineMode enabledInOffline; 
+  iSettings->GetOfflineModeSettings(offline, enabledInOffline);	
+  TRACE_FUNC_EXIT
+  return !offline; 	
+  }
+
+// ==========================================================
+// CBTToggle::SwitchBtOnWithPowerNotif
+// Switches BT on using Power Mode notifier   
+// ==========================================================
+//
+void CBTToggle::SwitchBtOnWithPowerNotif()
+  {	
+  TRACE_FUNC_ENTRY
+  __ASSERT_DEBUG(iActiveNotifier == ENoneQuery, Panic(EBTToggleInvalidStatePowerModeQuery));
+
+  iActiveNotifier = EPowerModeQuery;
+  // EBTNameQuery is used here as the message type, since the local device name may be modified by the user upon power-on.
+  iPckgGenericQuery().iMessageType = EBTNameQuery;			
+  iNotifier.StartNotifierAndGetResponse(iStatus, KPowerModeSettingNotifierUid, iPckgGenericQuery, iPowerResult );				
+  SetActive();
+  TRACE_FUNC_EXIT 	
+  }
+
+
+// ==========================================================
+// CBTToggle::ChangeBtPowerMode
+// Change BT Power Mode using CBTEngSettings API 
+// and show notification
+// ==========================================================
+//
+TInt CBTToggle::ChangeBtPowerMode(TBTPowerStateValue aNewPowerState)
+  {
+  TRACE_FUNC_ENTRY
+  __ASSERT_DEBUG(iActiveNotifier == ENoneQuery, Panic(EBTToggleInvalidStateChangeBtPowerMode));
+
+  TRequestStatus *stat = &iStatus; 
+  TInt errPower = iSettings->SetPowerState(aNewPowerState);					
+
+  if (KErrNone == errPower)
+    {
+    ShowNotification( static_cast<TBool>(aNewPowerState) );
+    }
+  iActiveNotifier = EFakeNotif; 
+  iStatus = KRequestPending;
+  User::RequestComplete(stat, KErrNone);
+  SetActive();
+
+  TRACE_FUNC_EXIT
+  return errPower; 	
+  }
+
+// ==========================================================
+// CBTToggle::ShowNotification
+// Presents generic info notification about BT on (ETrue) 
+// and BT off (EFalse)  
+// ==========================================================
+//
+void CBTToggle::ShowNotification( TBool aStatus )
+  {
+  TRACE_FUNC_ENTRY
+  TBTGenericInfoNotiferParamsPckg pckgGenericInfo; 	 	 	 
+  TBuf8<sizeof(TInt)> result;
+
+  //BT turned on
+  if (aStatus)
+    {
+    pckgGenericInfo().iMessageType = EBTSwitchedOn;  		 
+    }
+  //BT turned off
+  else
+    {
+    pckgGenericInfo().iMessageType = EBTSwitchedOff;		
+    }
+
+  //Cancel if there is any outstanding notification
+  Cancel();
+
+  //Start new notification
+  iNotifier.StartNotifier(KBTGenericInfoNotifierUid, pckgGenericInfo, result);	
+
+  TRACE_FUNC_EXIT
+  }
+
+// ==========================================================
+// CBTToggle::DoCancel
+// Cancel 
+// ==========================================================
+//
+void CBTToggle::DoCancel()
+  {	
+  TRACE_FUNC_ENTRY
+  if ( EPowerModeQuery == iActiveNotifier )
+    {
+    iNotifier.CancelNotifier(KPowerModeSettingNotifierUid); 		
+    }
+  else if ( ECloseConnectionQuery == iActiveNotifier ) 
+    {
+    iNotifier.CancelNotifier(KBTGenericQueryNotifierUid); 
+    }
+
+  // For all cancels, we must reset iActiveNotifier back to ENoneQuery
+  // to permit another request to be made.
+  iActiveNotifier = ENoneQuery;
+
+  TRACE_FUNC_EXIT
+  }
+
+// ==========================================================
+// CBTToggle::RunL
+// Inherited from CActive
+// ==========================================================
+//
+void CBTToggle::RunL()
+  {
+  TRACE_FUNC_ENTRY	
+
+  User::LeaveIfError(iStatus.Int());
+
+  // For all completes, we must reset iActiveNotifier back to ENoneQuery
+  // to permit another request to be made.
+  switch (iActiveNotifier)
+    {							
+    case EPowerModeQuery:				
+      iActiveNotifier = ENoneQuery;
+      ShowNotification(ETrue);
+      CActiveScheduler::Stop();
+      break; 			
+    case ECloseConnectionQuery:							
+      iActiveNotifier = ENoneQuery;
+      if (iConnQuery()) //user wants to stop existing connection
+        {
+        ChangeBtPowerMode(EBTPowerOff);										
+        }					
+      else
+        {
+        CActiveScheduler::Stop();
+        }																				
+      break;											
+    default: //ENoneQuery or EFakeNotif
+      iActiveNotifier = ENoneQuery;
+      CActiveScheduler::Stop();
+    }						
+  
+  TRACE_FUNC_EXIT	
+  }
+
+// ==========================================================
+// CBTToggle::RunError
+// Inherited from CActive
+// ==========================================================
+//
+TInt CBTToggle::RunError(TInt aError)
+  {	  
+  TRACE_INFO((_L("[BTENG][BTTOGGLE]RunL error %d"), aError ))		
+  CActiveScheduler::Stop();
+
+  return aError;
+  }