diff -r 000000000000 -r f63038272f30 bluetoothengine/bteng/bttoggle/src/bttoggle.cpp --- /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 +#include + +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 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(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 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; + }