bluetoothengine/bteng/bttoggle/src/bttoggle.cpp
changeset 0 f63038272f30
child 1 6a1fe72036e3
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Bluetooth Toggle application is being used by Telephony for 
       
    15  *  							switching on/off Bluetooth when a long key press of asterisk 
       
    16  *  							is detected 
       
    17  *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 //  Include Files  
       
    23 #include "bttoggle.h"
       
    24 #include "btengprivatecrkeys.h"
       
    25 #include "btengsrvbbconnectionmgr.h"
       
    26 #include "debug.h"
       
    27 
       
    28 #include <e32base.h>
       
    29 #include <e32std.h>
       
    30 
       
    31 void Panic(TBTTogglePanic aPanic)
       
    32   {
       
    33   User::Panic(KBTTogglePanicCat, aPanic);
       
    34   }
       
    35 
       
    36 LOCAL_C void DoStartL()
       
    37   {
       
    38   //Create active scheduler (to run active objects)
       
    39   CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
       
    40   CleanupStack::PushL (scheduler );
       
    41   CActiveScheduler::Install (scheduler );
       
    42 
       
    43   CBTToggle* bttoggle = CBTToggle::NewL();			
       
    44   bttoggle->ToggleBT();
       
    45 
       
    46   CActiveScheduler::Start();
       
    47 
       
    48   delete bttoggle; 		
       
    49   CleanupStack::PopAndDestroy (scheduler );
       
    50   return; 
       
    51   }
       
    52 
       
    53 //  Global Functions
       
    54 GLDEF_C TInt E32Main()
       
    55   {	 	
       
    56   CTrapCleanup* cleanup = CTrapCleanup::New();	
       
    57 
       
    58   // Run application code inside TRAP harness		
       
    59   TRAPD(mainError, DoStartL());
       
    60   if (mainError)
       
    61     {
       
    62     TRACE_INFO((_L("[BTENG][BTTOGGLE]DoStartL error: %d" ), mainError))
       
    63     }
       
    64   delete cleanup;		
       
    65   return KErrNone;
       
    66   }
       
    67 
       
    68 // ==========================================================
       
    69 // CBTToggle::CBTToggle()
       
    70 // Constructor
       
    71 // ==========================================================
       
    72 //
       
    73 CBTToggle::CBTToggle() : CActive(EPriorityStandard)
       
    74 		    {		
       
    75 		    }
       
    76 
       
    77 // ==========================================================
       
    78 // CBTToggle::~CBTToggle()
       
    79 // Destructor
       
    80 // ==========================================================
       
    81 //
       
    82 CBTToggle::~CBTToggle()
       
    83   {
       
    84   TRACE_FUNC_ENTRY
       
    85 
       
    86   Cancel(); 		
       
    87   delete iSettings; 	
       
    88   iNotifier.Close();		
       
    89   iLinkCountProperty.Close();
       
    90 
       
    91   TRACE_FUNC_EXIT
       
    92   }
       
    93 
       
    94 // ==========================================================
       
    95 // CBTToggle::ConstructL
       
    96 // 
       
    97 // ==========================================================
       
    98 //
       
    99 void CBTToggle::ConstructL()
       
   100   {
       
   101   TRACE_FUNC_ENTRY		
       
   102   iSettings = CBTEngSettings::NewL(NULL);	
       
   103   CActiveScheduler::Add(this); 	
       
   104   iActiveNotifier = ENoneQuery; 
       
   105   TInt errConnect = iNotifier.Connect();	
       
   106   if (errConnect)
       
   107     {
       
   108     TRACE_INFO((_L("[BTENG][BTTOGGLE] iNotifier connect fail: %d" ), errConnect))
       
   109     User::Leave(errConnect);
       
   110     }				
       
   111   User::LeaveIfError( iLinkCountProperty.Attach( KPropertyUidBluetoothCategory, 
       
   112       KPropertyKeyBluetoothGetPHYCount ) );	  
       
   113   TRACE_FUNC_EXIT
       
   114   }
       
   115 
       
   116 // ==========================================================
       
   117 // CBTToggle::NewL
       
   118 //
       
   119 // ==========================================================
       
   120 //
       
   121 CBTToggle* CBTToggle::NewL()
       
   122   {
       
   123   TRACE_FUNC_ENTRY
       
   124   CBTToggle* self = new ( ELeave ) CBTToggle();
       
   125   CleanupStack::PushL(self);  
       
   126   self->ConstructL();
       
   127   CleanupStack::Pop(self);
       
   128   TRACE_FUNC_EXIT
       
   129   return self; 
       
   130   }
       
   131 
       
   132 // ==========================================================
       
   133 // CBTToggle::ToggleBT
       
   134 // Toggles Bluetooth on or off and shows dialog 
       
   135 // (if the BT is switched for the first time after flashing)
       
   136 // and notification
       
   137 // ==========================================================
       
   138 //
       
   139 void CBTToggle::ToggleBT()
       
   140   {
       
   141   TRACE_FUNC_ENTRY	
       
   142 
       
   143   TBTPowerStateValue state;	
       
   144   iSettings->GetPowerState(state);	  
       
   145 
       
   146   //BT off
       
   147   if (EBTPowerOff == state)
       
   148     {					
       
   149     TBool isInOffline = CheckOfflineMode(); 
       
   150     if (isInOffline) //Offline mode
       
   151       {					
       
   152       TRACE_INFO((_L("[BTENG][BTTOGGLE]Offline mode") ))
       
   153       SwitchBtOnWithPowerNotif(); 						
       
   154       }
       
   155     else //other than offline
       
   156       {									
       
   157       TBuf<KHCILocalDeviceNameMaxLength> localName;
       
   158       iSettings->GetLocalName(localName);														
       
   159 
       
   160       //There is no BT local name defined		
       
   161       if (0 >= localName.Length()) 
       
   162         {																
       
   163         SwitchBtOnWithPowerNotif(); 
       
   164         }
       
   165       else //BT name already defined
       
   166         {				
       
   167         ChangeBtPowerMode(EBTPowerOn);
       
   168         }				
       
   169       } 		
       
   170     } 	
       
   171   else //BT on 
       
   172     {				
       
   173     TInt linkCount = 0; 
       
   174     TInt errLinkCount = iLinkCountProperty.Get( linkCount );		
       
   175     TRACE_INFO((_L("[BTENG][BTTOGGLE] linkCount: %d error: %d" ), linkCount, errLinkCount))		
       
   176 
       
   177     //BT Connected or error obtaining link count (in the case of error, we are cautious and assume BT is connected)
       
   178     if (errLinkCount || linkCount > 0)
       
   179       {
       
   180       TRACE_INFO((_L("[BTENG][BTTOGGLE]Ongoing BT connection") ))								
       
   181       __ASSERT_DEBUG(iActiveNotifier == ENoneQuery, Panic(EBTToggleInvalidStateCloseConnectionQuery));
       
   182 
       
   183       iActiveNotifier = ECloseConnectionQuery;						
       
   184       iPckgGenericQuery().iMessageType = EBTSwitchOffAnyway;
       
   185       iPckgGenericQuery().iNameExists = EFalse;
       
   186       iNotifier.StartNotifierAndGetResponse(iStatus, KBTGenericQueryNotifierUid, iPckgGenericQuery, iConnQuery );			
       
   187       SetActive();															
       
   188       }	
       
   189     //No open connections
       
   190     else
       
   191       {
       
   192       TRACE_INFO((_L("[BTENG][BTTOGGLE] No BT connections") ))
       
   193       ChangeBtPowerMode(EBTPowerOff);
       
   194       }					 
       
   195     }
       
   196   TRACE_FUNC_EXIT	
       
   197   }
       
   198 
       
   199 // ==========================================================
       
   200 // CBTToggle::CheckOfflineMode
       
   201 // Checks whether current profile is Offline  
       
   202 // ==========================================================
       
   203 //
       
   204 TBool CBTToggle::CheckOfflineMode()
       
   205   {
       
   206   TRACE_FUNC_ENTRY
       
   207   TCoreAppUIsNetworkConnectionAllowed offline = ECoreAppUIsNetworkConnectionAllowed;  
       
   208   TBTEnabledInOfflineMode enabledInOffline; 
       
   209   iSettings->GetOfflineModeSettings(offline, enabledInOffline);	
       
   210   TRACE_FUNC_EXIT
       
   211   return !offline; 	
       
   212   }
       
   213 
       
   214 // ==========================================================
       
   215 // CBTToggle::SwitchBtOnWithPowerNotif
       
   216 // Switches BT on using Power Mode notifier   
       
   217 // ==========================================================
       
   218 //
       
   219 void CBTToggle::SwitchBtOnWithPowerNotif()
       
   220   {	
       
   221   TRACE_FUNC_ENTRY
       
   222   __ASSERT_DEBUG(iActiveNotifier == ENoneQuery, Panic(EBTToggleInvalidStatePowerModeQuery));
       
   223 
       
   224   iActiveNotifier = EPowerModeQuery;
       
   225   // EBTNameQuery is used here as the message type, since the local device name may be modified by the user upon power-on.
       
   226   iPckgGenericQuery().iMessageType = EBTNameQuery;			
       
   227   iNotifier.StartNotifierAndGetResponse(iStatus, KPowerModeSettingNotifierUid, iPckgGenericQuery, iPowerResult );				
       
   228   SetActive();
       
   229   TRACE_FUNC_EXIT 	
       
   230   }
       
   231 
       
   232 
       
   233 // ==========================================================
       
   234 // CBTToggle::ChangeBtPowerMode
       
   235 // Change BT Power Mode using CBTEngSettings API 
       
   236 // and show notification
       
   237 // ==========================================================
       
   238 //
       
   239 TInt CBTToggle::ChangeBtPowerMode(TBTPowerStateValue aNewPowerState)
       
   240   {
       
   241   TRACE_FUNC_ENTRY
       
   242   __ASSERT_DEBUG(iActiveNotifier == ENoneQuery, Panic(EBTToggleInvalidStateChangeBtPowerMode));
       
   243 
       
   244   TRequestStatus *stat = &iStatus; 
       
   245   TInt errPower = iSettings->SetPowerState(aNewPowerState);					
       
   246 
       
   247   if (KErrNone == errPower)
       
   248     {
       
   249     ShowNotification( static_cast<TBool>(aNewPowerState) );
       
   250     }
       
   251   iActiveNotifier = EFakeNotif; 
       
   252   iStatus = KRequestPending;
       
   253   User::RequestComplete(stat, KErrNone);
       
   254   SetActive();
       
   255 
       
   256   TRACE_FUNC_EXIT
       
   257   return errPower; 	
       
   258   }
       
   259 
       
   260 // ==========================================================
       
   261 // CBTToggle::ShowNotification
       
   262 // Presents generic info notification about BT on (ETrue) 
       
   263 // and BT off (EFalse)  
       
   264 // ==========================================================
       
   265 //
       
   266 void CBTToggle::ShowNotification( TBool aStatus )
       
   267   {
       
   268   TRACE_FUNC_ENTRY
       
   269   TBTGenericInfoNotiferParamsPckg pckgGenericInfo; 	 	 	 
       
   270   TBuf8<sizeof(TInt)> result;
       
   271 
       
   272   //BT turned on
       
   273   if (aStatus)
       
   274     {
       
   275     pckgGenericInfo().iMessageType = EBTSwitchedOn;  		 
       
   276     }
       
   277   //BT turned off
       
   278   else
       
   279     {
       
   280     pckgGenericInfo().iMessageType = EBTSwitchedOff;		
       
   281     }
       
   282 
       
   283   //Cancel if there is any outstanding notification
       
   284   Cancel();
       
   285 
       
   286   //Start new notification
       
   287   iNotifier.StartNotifier(KBTGenericInfoNotifierUid, pckgGenericInfo, result);	
       
   288 
       
   289   TRACE_FUNC_EXIT
       
   290   }
       
   291 
       
   292 // ==========================================================
       
   293 // CBTToggle::DoCancel
       
   294 // Cancel 
       
   295 // ==========================================================
       
   296 //
       
   297 void CBTToggle::DoCancel()
       
   298   {	
       
   299   TRACE_FUNC_ENTRY
       
   300   if ( EPowerModeQuery == iActiveNotifier )
       
   301     {
       
   302     iNotifier.CancelNotifier(KPowerModeSettingNotifierUid); 		
       
   303     }
       
   304   else if ( ECloseConnectionQuery == iActiveNotifier ) 
       
   305     {
       
   306     iNotifier.CancelNotifier(KBTGenericQueryNotifierUid); 
       
   307     }
       
   308 
       
   309   // For all cancels, we must reset iActiveNotifier back to ENoneQuery
       
   310   // to permit another request to be made.
       
   311   iActiveNotifier = ENoneQuery;
       
   312 
       
   313   TRACE_FUNC_EXIT
       
   314   }
       
   315 
       
   316 // ==========================================================
       
   317 // CBTToggle::RunL
       
   318 // Inherited from CActive
       
   319 // ==========================================================
       
   320 //
       
   321 void CBTToggle::RunL()
       
   322   {
       
   323   TRACE_FUNC_ENTRY	
       
   324 
       
   325   User::LeaveIfError(iStatus.Int());
       
   326 
       
   327   // For all completes, we must reset iActiveNotifier back to ENoneQuery
       
   328   // to permit another request to be made.
       
   329   switch (iActiveNotifier)
       
   330     {							
       
   331     case EPowerModeQuery:				
       
   332       iActiveNotifier = ENoneQuery;
       
   333       ShowNotification(ETrue);
       
   334       CActiveScheduler::Stop();
       
   335       break; 			
       
   336     case ECloseConnectionQuery:							
       
   337       iActiveNotifier = ENoneQuery;
       
   338       if (iConnQuery()) //user wants to stop existing connection
       
   339         {
       
   340         ChangeBtPowerMode(EBTPowerOff);										
       
   341         }					
       
   342       else
       
   343         {
       
   344         CActiveScheduler::Stop();
       
   345         }																				
       
   346       break;											
       
   347     default: //ENoneQuery or EFakeNotif
       
   348       iActiveNotifier = ENoneQuery;
       
   349       CActiveScheduler::Stop();
       
   350     }						
       
   351   
       
   352   TRACE_FUNC_EXIT	
       
   353   }
       
   354 
       
   355 // ==========================================================
       
   356 // CBTToggle::RunError
       
   357 // Inherited from CActive
       
   358 // ==========================================================
       
   359 //
       
   360 TInt CBTToggle::RunError(TInt aError)
       
   361   {	  
       
   362   TRACE_INFO((_L("[BTENG][BTTOGGLE]RunL error %d"), aError ))		
       
   363   CActiveScheduler::Stop();
       
   364 
       
   365   return aError;
       
   366   }