diff -r 000000000000 -r f63038272f30 bluetoothengine/btui/Ecom/src/BTUIPairedDevicesView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/btui/Ecom/src/BTUIPairedDevicesView.cpp Mon Jan 18 20:28:57 2010 +0200 @@ -0,0 +1,1914 @@ +/* +* Copyright (c) 2002,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: This is view that handles listing and + * unblocking blocked devices view. + * +*/ + +#include // AVKON components +#include +#include +#include // Compiled resource ids +#include // Feature Manager + +#include +#include +#include // Series 60 localisation stringloader +#include +#include +#include +#include +#include // Help launcher +#include // for device search + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "btui.h" // Global declarations +#include "BTUIPairedDevicesView.h" +#include "BTUIDeviceContainer.h" +#include +#include // Help IDs + +#include +#include // Tab icon for General Setting +#include "BTUIMainView.h" // base View. + +const TInt KAutoConnect2ndTry = 1; +const TUint32 SetExcludePairedDeviceMask = 0x800000; + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CBTUIPairedDevicesView::NewL +// Two phased constructor called by BT AppUI when serve as part of btui.exe +// --------------------------------------------------------- +// +CBTUIPairedDevicesView* CBTUIPairedDevicesView::NewL(MBtuiPluginViewActivationObserver* aObserver) + { + CBTUIPairedDevicesView* self = new (ELeave) CBTUIPairedDevicesView(aObserver); + CleanupStack::PushL(self); + + self->iConstructAsGsPlugin = EFalse; + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------- +// CBTUIPairedDevicesView::NewLC +// Two phased constructor called by mainView when serve as GS Plugin. +// --------------------------------------------------------- +// +CBTUIPairedDevicesView* CBTUIPairedDevicesView::NewLC(CBTUIMainView* aBaseView, CArrayPtrFlat* aTabViewArray) + { + CBTUIPairedDevicesView* self = new (ELeave) CBTUIPairedDevicesView(); + CleanupStack::PushL( self ); + + self->iConstructAsGsPlugin = ETrue; + self->ConstructL( aBaseView, aTabViewArray ); + + return self; + } + + +// --------------------------------------------------------- +// CBTUIPairedDevicesView::ConstructL +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------- +// +void CBTUIPairedDevicesView::ConstructL() + { + TRACE_FUNC_ENTRY + + BaseConstructL(R_BTUI_OTHER_DEVICES_VIEW); + + iCoverDisplayEnabled = FeatureManager::FeatureSupported(KFeatureIdCoverDisplay); + iHelpEnabled = FeatureManager::FeatureSupported(KFeatureIdHelp); + + iDeviceSearcher = CBTEngDiscovery::NewL(this); + iBtEngSettings = CBTEngSettings::NewL(this); + iBTPluginMan = CBTUIPluginMan::NewL( AppUi() ); + iIsAlreadyConnected = EFalse; + iExpectedCallBack = 0; + TRACE_INFO(_L("Initial iIsAlreadyConnected -> False")) + TRACE_FUNC_EXIT + } + +void CBTUIPairedDevicesView::ConstructL( CBTUIMainView* aBaseView, CArrayPtrFlat* aTabViewArray ) + { + TRACE_FUNC_ENTRY + + iBaseView = aBaseView, + iTabHelper = CGSTabHelper::NewL(); + aTabViewArray->AppendL(this); + + BaseConstructL(R_BTUI_OTHER_DEVICES_VIEW_GS); + iCoverDisplayEnabled = FeatureManager::FeatureSupported(KFeatureIdCoverDisplay); + iHelpEnabled = FeatureManager::FeatureSupported(KFeatureIdHelp); + + iDeviceSearcher = CBTEngDiscovery::NewL(this); + iBtEngSettings=CBTEngSettings::NewL(this); + iBTPluginMan = CBTUIPluginMan::NewL( AppUi() ); + iIsAlreadyConnected = EFalse; + TRACE_INFO(_L("Initial iIsAlreadyConnected = False")) + iExpectedCallBack = 0; + + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------- +// CBTUIBlockedDevicesView::CBTUIBlockedDevicesView +// --------------------------------------------------------- + +CBTUIPairedDevicesView::CBTUIPairedDevicesView( MBtuiPluginViewActivationObserver* aObserver ) + : iActivationObserver(aObserver) + { + } + +// --------------------------------------------------------- +// Destructor +// --------------------------------------------------------- +// +CBTUIPairedDevicesView::~CBTUIPairedDevicesView() + { + TRACE_FUNC_ENTRY + + //close dialogs if any + TRAP_IGNORE( + DialogDismissedL(EAknSoftkeyCancel); + ); + + delete iActive; + + if (iContainer) + { + AppUi()->RemoveFromViewStack(*this, iContainer); + delete iContainer; + iContainer = NULL; + } + + if(iDeviceSearcher) + { + // Canceling devicesearches is done by DialogDismissedL(), + // so it is not done here + delete iDeviceSearcher; + iDeviceSearcher = NULL ; + } + delete iConnectDevice; + iConnectDevice=NULL; + + delete iPairingDevice; + delete iBtEngSettings; + delete iBTPluginMan; + + if(iConstructAsGsPlugin) + delete iTabHelper; + + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------- +// From CAknView +// CBTUIPairedDevicesView::Id +// --------------------------------------------------------- +// +TUid CBTUIPairedDevicesView::Id() const + { + TRACE_FUNC_ENTRY + return KBtuiPluginUidPairedDevicesView;//KBTOtherDevicesViewId; + } + + + + +// --------------------------------------------------------- +// From CAknView +// CBTUIPairedDevicesView::HandleCommandL +// Redirects commands to the appui class. +// --------------------------------------------------------- +// +void CBTUIPairedDevicesView::HandleCommandL(TInt aCommand) + { + TRACE_FUNC_ENTRY + + switch (aCommand) + { + + case EAknSoftkeyBack: + // do not exit if devicechange is in progress. + if(iModel->DeviceChangeInProgress() ) + return; + AppUi()->ActivateLocalViewL(iBaseView->GetParentView().iViewUid ); + break; + + case EAknSoftkeyExit: + { + TRACE_INFO(_L("EAknSoftkeyExit")) + // do not exit if devicechange or bt discovery is in progress. + if(iModel->DeviceChangeInProgress() + || iSearchOngoing ) + { + TRACE_INFO(_L("exit denied, due to operation")) + return; + } + + TRACE_INFO(_L("exit in progress")) + AppUi()->ProcessCommandL(EEikCmdExit); + break; + } + + case EAknCmdHelp: + { + #ifdef __SERIES60_HELP + HlpLauncher::LaunchHelpApplicationL(iEikonEnv->WsSession(),AppUi()->AppHelpContextL()); + #endif + break; + } + + case EBTUICmdNewPairedDevice: + { + iSearchOngoing=ETrue; + NewPairedDeviceDlgL(); + break; + } + + case EBTUICmdDelete: + { + DeleteDeviceDlgL(); + break; + } + + case EBTUICmdDeleteAll: + { + DeleteAllDevicesDlgL(); + break; + } + + case EBTUICmdGiveNickname: + { + RenameDeviceDlgL(); + break; + } + + case EBTUICmdSetTrusted: + { + ChangeDeviceSecurityL(ETrue); + break; + } + + case EBTUICmdSetUnTrusted: + { + ChangeDeviceSecurityL(EFalse); + break; + } + + case EBTUICmdConnect: + case EBTUICmdConnectAudio: + { + TBTDevice device; + device.iIndex = iContainer->CurrentItemIndex(); + iModel->GetDevice(device); + device.iOperation = EOpConnect; + ConnectL( device, ETrue ); + break; + } + + case EBTUICmdDisconnect: + { + DisconnectL(); + break; + } + + case EBTUICmdSetBlocked: + { + BlockDeviceDlgL(); + break; + } + + case EBTUICmdSettings: + { + LaunchSettingViewL(); + break; + } + + default: + { + AppUi()->HandleCommandL(aCommand); + break; + } + } + TRACE_FUNC_EXIT + } + + +// --------------------------------------------------------- +// From CAknView +// CBTUIPairedDevicesView::DoActivateL +// --------------------------------------------------------- +// +void CBTUIPairedDevicesView::DoActivateL(const TVwsViewId& /*aPrevViewId*/, + TUid /*aCustomMessageId*/, + const TDesC8& /*aCustomMessage*/) + { + TRACE_FUNC_ENTRY + + iModel = CBTDevModel::NewL(EGroupPaired, this); + iContainer = CBTUiDeviceContainer::NewL(ClientRect(), this, EGroupPaired, this); + iContainer->SetMopParent(this); // MObjectProvider + + // Setup title + HBufC* btTitlePairedDevices = + iCoeEnv->AllocReadResourceLC(R_BT_TITLE_PAIRED_DEV); + CEikStatusPane* statusPane = StatusPane(); + CAknTitlePane* titlePane; + titlePane = (CAknTitlePane*) statusPane->ControlL( + TUid::Uid(EEikStatusPaneUidTitle)); + titlePane->SetTextL(btTitlePairedDevices->Des()); + CleanupStack::PopAndDestroy(btTitlePairedDevices); // btTitlePairedDevices + btTitlePairedDevices = NULL; + + AppUi()->AddToStackL(*this, iContainer); + + if( iBaseView && iConstructAsGsPlugin) + { + iTabHelper->CreateTabGroupL( Id(), + static_cast*> + (iBaseView->TabbedViews()) ); + } + + // MSK menu is added here. + // the left key menu is added by resources. + MenuBar()->SetContextMenuTitleResourceId( + R_BTUI_MENUBAR_OTHER_DEVICES_VIEW_CONTEXT); + // notify observer + if( iActivationObserver && iConstructAsGsPlugin == EFalse) + { + iActivationObserver->PluginViewActivated(EPairedDevicesViewId); + } + + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------- +// From CAknView +// CBTUIPairedDevicesView::DoDeactivate +// --------------------------------------------------------- +// +void CBTUIPairedDevicesView::DoDeactivate() + { + TRACE_FUNC_ENTRY + + if (iContainer) + { + AppUi()->RemoveFromStack(iContainer); + delete iContainer; + iContainer = NULL; + } + if ( iDeviceSearcher ) + { + iDeviceSearcher->CancelSearchRemoteDevice(); + } + delete iModel; + iModel=NULL; + if(iConstructAsGsPlugin) + iTabHelper->RemoveTabGroup(); + delete iActive; + iActive = NULL; + iIsPairConnect = EFalse; + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------- +// From CAknView +// CBTUIPairedDevicesView::DynInitMenuPaneL +// Shows only options supported for selected device, if any. +// If not show only options supported regardless of selected +// device +// --------------------------------------------------------- +// +void CBTUIPairedDevicesView::DynInitMenuPaneL(TInt aResId, CEikMenuPane* aMenu) + { + TRACE_FUNC_ENTRY + iActiveMenuPane = aMenu; + // dim help if it exists and is not supported + TInt tmp; + if ( aMenu->MenuItemExists(EAknCmdHelp,tmp ) ) + { + aMenu->SetItemDimmed(EAknCmdHelp, + !FeatureManager::FeatureSupported( KFeatureIdHelp ) ); + } + + if ( aResId == R_BTUI_OTHER_DEVICES_VIEW_MENU ) + { + TInt index = iContainer->CurrentItemIndex(); + + // we only show "new pair device", "help" , "Exit" and "Delete All" if view contains device(s). + aMenu->SetItemDimmed(EBTUICmdSetTrusted, ETrue); + aMenu->SetItemDimmed(EBTUICmdDelete,ETrue); + aMenu->SetItemDimmed(EBTUICmdSetTrusted,ETrue); + aMenu->SetItemDimmed(EBTUICmdSetUnTrusted,ETrue); + aMenu->SetItemDimmed(EBTUICmdConnect,ETrue); + aMenu->SetItemDimmed(EBTUICmdConnectAudio,ETrue); + aMenu->SetItemDimmed(EBTUICmdDisconnect,ETrue); + aMenu->SetItemDimmed(EBTUICmdSetBlocked,ETrue); + aMenu->SetItemDimmed(EBTUICmdSettings,ETrue); + aMenu->SetItemDimmed(EBTUICmdGiveNickname, ETrue); + + if ( index < 0 ) // No devices at list. Hide all device related commands. + { + aMenu->SetItemDimmed(EBTUICmdDeleteAll, ETrue); + } + + } + + if ( aResId == R_BTUI_OTHER_DEVICES_VIEW_MENU_CONTEXT ) + { + TInt index = iContainer->CurrentItemIndex(); + + // If user is fast enough to click the RSK option between + // bt discovery view and device found view, bt ui will crash. + // Therefore, we disable commands if bt discovery is onging. + // + if(iSearchOngoing) + { + aMenu->SetItemDimmed(EBTUICmdGiveNickname, ETrue); + aMenu->SetItemDimmed(EBTUICmdSetTrusted, ETrue); + aMenu->SetItemDimmed(EBTUICmdSetUnTrusted, ETrue); + aMenu->SetItemDimmed(EBTUICmdSetBlocked, ETrue); + aMenu->SetItemDimmed(EBTUICmdDelete, ETrue); + aMenu->SetItemDimmed(EBTUICmdConnect, ETrue); + aMenu->SetItemDimmed(EBTUICmdConnectAudio, ETrue); + aMenu->SetItemDimmed(EBTUICmdDisconnect, ETrue); + aMenu->SetItemDimmed(EBTUICmdNewPairedDevice, ETrue); + return; + } + + if(index < 0) // No devices at list. Hide all device related commands. + { + TRACE_INFO(_L("no devices in list")) + + aMenu->SetItemDimmed(EBTUICmdGiveNickname, ETrue); + aMenu->SetItemDimmed(EBTUICmdSetTrusted, ETrue); + aMenu->SetItemDimmed(EBTUICmdSetUnTrusted, ETrue); + aMenu->SetItemDimmed(EBTUICmdSetBlocked, ETrue); + aMenu->SetItemDimmed(EBTUICmdDelete, ETrue); + aMenu->SetItemDimmed(EBTUICmdConnect, ETrue); + aMenu->SetItemDimmed(EBTUICmdConnectAudio, ETrue); + aMenu->SetItemDimmed(EBTUICmdDisconnect, ETrue); + aMenu->SetItemDimmed(EBTUICmdSettings, ETrue); + } + else // There are devices at list + { + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + iMenuDevice = device; + + TRACE_INFO(_L("there are device in list")) + + TBool dim = (device.iStatus & EStatusTrusted) == EStatusTrusted; + + aMenu->SetItemDimmed(EBTUICmdSetTrusted, dim); + aMenu->SetItemDimmed(EBTUICmdSetUnTrusted, !dim); + + // Check if device can be connected or disconnected + dim = (! (device.iStatus & EStatusConnectable) + || device.iStatus & EStatusBtuiConnected); + + if (dim) + { + aMenu->SetItemDimmed(EBTUICmdConnect, dim); + aMenu->SetItemDimmed(EBTUICmdConnectAudio, dim); + } + else + { + if ( device.iDeviceClass.MajorDeviceClass() == EMajorDeviceComputer) + { + aMenu->SetItemDimmed(EBTUICmdConnect, ETrue); + } + else + { + aMenu->SetItemDimmed(EBTUICmdConnectAudio, ETrue); + } + } + dim = (device.iStatus & EStatusBtuiConnected) != EStatusBtuiConnected; + aMenu->SetItemDimmed(EBTUICmdDisconnect, dim); + + if ( !iBTPluginMan->IsPluginAvaiable(device.iDeviceClass) ) + { + aMenu->SetItemDimmed(EBTUICmdSettings, ETrue); + } + else + { + dim = (device.iStatus & EStatusBtuiConnected) != EStatusBtuiConnected; + aMenu->SetItemDimmed(EBTUICmdSettings, dim); + } + //Hide New pair device + aMenu->SetItemDimmed(EBTUICmdNewPairedDevice, ETrue); + } + } + TRACE_FUNC_EXIT + } + + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::RenameDeviceDlgL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::RenameDeviceDlgL() + { + TRACE_FUNC_ENTRY + + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + TBTDeviceName name = device.iName; + + CAknTextQueryDialog* dlg = CAknTextQueryDialog::NewL(device.iName); + TInt keypress = dlg->ExecuteLD(R_BT_ENTER_NICKNAME_QUERY); + + if(keypress) // User has accepted the dialog + { + if(device.iName != name) // Check if the user really changed the name + { + device.iOperation = EOpChangeName; + // Remove trouble making control chars + AknTextUtils::StripCharacters(device.iName, KAknStripListControlChars); + device.iName.TrimAll(); // Remove extra spaces + iModel->ChangeDevice(device); + } + } + TRACE_FUNC_EXIT + } + + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::NewPairedDeviceDlgL +// +// Initiate bonding (pairing) by opening the search dialog. +// DeviceSearchComplete is called after that. +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::NewPairedDeviceDlgL() + { + TRACE_FUNC_ENTRY + // we must not have other pairing in progress. + // we maight issue an error, but none is defined by + // ui spec. Anyhow this should be possible + // only by pressing everything roo rapidly. + if(iPairingDevice!=NULL) + return; + iPairingDevice = CBTDevice::NewL(); + + // Here we use last bit in device class to inform bt inquiry notifier + // not to display the device which is already paired and in the paired + // device list. + + // We use DeviceClass to tell btnotif not to show paired device in + // bt discovery notifier through bteng. + // Set bit 24 to 1 ( bit 24 is not used for any other purpose currently ) + iPairingDevice->SetDeviceClass(iPairingDevice->DeviceClass().DeviceClass() | SetExcludePairedDeviceMask ); + TInt err = iDeviceSearcher->SearchRemoteDevice(iPairingDevice, + &iPairingDevNameEntry, + iPairingDevice->DeviceClass().DeviceClass()); + + + if(err != KErrNone) + { + delete iPairingDevice; + iPairingDevice=NULL; + TBTUIViewsCommonUtils::ShowGeneralErrorNoteL(); + } + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::DeleteDeviceDlgL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::DeleteDeviceDlgL() + { + TRACE_FUNC_ENTRY + + iExpectedCallBack = 0; + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + + HBufC* stringholder = NULL; + + TInt tmp=EStatusBtuiConnected|EStatusPhysicallyConnected; + // Choose confirmation phrase + // + if ( device.iStatus & tmp ) + { + stringholder = StringLoader::LoadLC(R_BT_WARN_ERASE_CONNECTED, + device.iName); + } + else + { + stringholder = StringLoader::LoadLC(R_BT_WARN_ERASE, device.iName ); + } + + // Create confirmation query + // + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(dlg); + dlg->PublishDialogL(ECmdShowBtWarnEraseNote, KUidCoverUiCategoryBtui); + // initializes cover support + CleanupStack::Pop(dlg); + + CAknMediatorFacade* covercl = AknMediatorFacade(dlg); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(device.iName) ;// takes copy so consts are ok too + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + TInt keypress = dlg->ExecuteLD(R_BT_WARN_ERASE_QUERY, *stringholder); + + CleanupStack::PopAndDestroy(stringholder); // stringholder + + if(keypress) // User has accepted the dialog + { + // If device is connected we need to first to disconnect + // then unpair, otherwise unpairing does not succeed. + if((device.iStatus & EStatusBtuiConnected) == EStatusBtuiConnected) + { + iExpectedCallBack++; + DisconnectWithoutQuery(); + return; + } + device.iOperation = EOpUnpair; + iModel->ChangeDevice(device); + } + + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::DeleteAllDevicesDlgL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::DeleteAllDevicesDlgL() + { + TRACE_FUNC_ENTRY + + iExpectedCallBack = 0; + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + TInt keypress = KErrNone; + + CleanupStack::PushL(dlg); + + // Choose and execute confirmation query + // + if (iModel->IsAnyDeviceConnected()) + { + if(iCoverDisplayEnabled) + { + dlg->PublishDialogL(ECmdShowBtWarnEraseAllConnectedQuery, KUidCoverUiCategoryBtui); // initializes cover support + } + + keypress = dlg->ExecuteLD(R_BT_WARN_ERASE_ALL_CONNECTED_QUERY); + } + else + { + if(iCoverDisplayEnabled) + { + dlg->PublishDialogL(ECmdShowBtWarnEraseAllQuery, KUidCoverUiCategoryBtui); // initializes cover support + } + + keypress = dlg->ExecuteLD(R_BT_WARN_ERASE_ALL_QUERY); + } + CleanupStack::Pop(dlg); + + if(keypress) // User has accepted the dialog + { + TInt count = iContainer->CountItems(); + for (TInt i = 0; i < count; i++) + { + // If device is connected we need to first to disconnect + // then unpair, otherwise unpairing does not succeed. + TBTDevice device; + device.iIndex = i; + iModel->GetDevice(device); + if((device.iStatus & EStatusBtuiConnected) == EStatusBtuiConnected) + { + iExpectedCallBack++; + } + } + TRACE_INFO((_L("iExpectedCallBack %d"), iExpectedCallBack )) + + for (TInt i = 0; i < count; i++) + { + // If device is connected we need to first to disconnect + // then unpair, otherwise unpairing does not succeed. + TBTDevice device; + device.iIndex = i; + iModel->GetDevice(device); + + if((device.iStatus & EStatusBtuiConnected) == EStatusBtuiConnected) + { + //disconnect it first, removal will be done in + //callback NotifyChangeDeviceCompleteL for ChangeDevice() below + TRACE_INFO((_L("EOpDisconnect issued for %d"), i )) + device.iOperation = EOpDisconnect; + iModel->ChangeDevice(device); + } + else + { + //otherwise, just remove it from the paired view + device.iOperation = EOpUnpair; + iModel->ChangeDevice(device); + } + } + } + + TRACE_FUNC_EXIT + } +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::BlockDeviceDlgL +// ---------------------------------------------------------- +void CBTUIPairedDevicesView::BlockDeviceDlgL() + { + TRACE_FUNC_ENTRY + + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + + //check if this is connected device + + HBufC* header= iCoeEnv->AllocReadResourceLC(R_BT_OPTION_BLOCK_DEVICE_HEADER); + + HBufC* stringHolder = NULL; + if (device.iStatus & (EStatusBtuiConnected|EStatusPhysicallyConnected) ) + stringHolder = StringLoader::LoadLC( + (iHelpEnabled? R_BT_OPTION_BLOCK_CONNECTED_PAIRED_DEVICES_HELP: + R_BT_OPTION_BLOCK_CONNECTED_PAIRED_DEVICES_NOHELP ), + device.iName); + else + stringHolder = StringLoader::LoadLC( + (iHelpEnabled?R_BT_OPTION_BLOCK_PAIRED_DEVICE_HELP:R_BT_OPTION_BLOCK_PAIRED_DEVICE_NOHELP), + device.iName); + + + CAknMessageQueryDialog *queryDialog = CAknMessageQueryDialog::NewL (*stringHolder, + CAknQueryDialog::EConfirmationTone); + queryDialog->PrepareLC(R_BT_MESSAGE_QUERY); + + (queryDialog)->Heading()->SetTextL(*header); + queryDialog->SetFocus(ETrue); + + TInt keypress=EFalse; +#ifdef __SERIES60_HELP + if (iHelpEnabled) + { + HBufC* queryLink = StringLoader::LoadL(R_BT_BLOCK_DEVICE_LINK); + TCoeHelpContext hc(KBtuiUid3,KBT_HLP_BLOCKED); + TCallBack helpCallBack(CBTUIPairedDevicesView::LaunchHelp , &hc); + + TRAPD(err, + static_cast(queryDialog)->SetLinkTextL(*queryLink); + static_cast(queryDialog)->SetLink(helpCallBack);); + if(err==KErrNone) + { + keypress = queryDialog->RunLD(); + } + + delete queryLink; + queryLink = NULL; + } + else +#endif + { + keypress = queryDialog->RunLD(); + } + + CleanupStack::PopAndDestroy(stringHolder); + CleanupStack::PopAndDestroy(header); + + if(keypress) + { + device.iOperation = EOpBlock; + iModel->ChangeDevice(device); + } + TRACE_FUNC_EXIT + } +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::ChangeDeviceSecurityL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::ChangeDeviceSecurityL(TBool aTrusted) + { + TRACE_FUNC_ENTRY + + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + + if(aTrusted) + { + // set to trusted + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(dlg); + dlg->PublishDialogL(ECmdShowBtAuthConfirmQuery, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(dlg); + } + TInt keypress = dlg->ExecuteLD(R_BT_SET_TRUSTED_QUERY); + + if(keypress) // User has accepted the dialog + { + device.iOperation = EOpTrust; + iModel->ChangeDevice(device); + } + } + else + { + device.iOperation = EOpUntrust; + iModel->ChangeDevice(device); + } + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------- +// CBTUIMainView::VisibilityModeChanged +// ---------------------------------------------------- +// +void CBTUIPairedDevicesView::VisibilityModeChanged( TBTVisibilityMode ) + { + TRACE_FUNC_ENTRY + + + TRACE_FUNC_EXIT + } + + +// ---------------------------------------------------- +// CBTUIMainView::PowerStateChanged +// ---------------------------------------------------- +// +void CBTUIPairedDevicesView::PowerStateChanged( TBTPowerStateValue ) + { + TRACE_FUNC_ENTRY + + if ( iIsConnectDevice ) + { + iModel->ChangeDevice(*iConnectDevice); + iIsConnectDevice = EFalse; // reset flag + } + + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::ConnectL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::ConnectL( + const TBTDevice& aDevice, TBool aNewWaitNote ) + { + TRACE_FUNC_ENTRY + + iIsAlreadyConnected = EFalse; + TRACE_INFO(_L("Set iIsAlreadyConnected -> False")) + //Check that there is not more than max amount of connections allready. + TInt connNum = 0; + RProperty::Get(KPropertyUidBluetoothCategory, KPropertyKeyBluetoothPHYCount, connNum); + if(connNum > KBtUiMaxConnections) + { + ConnectCompleteL(KErrServerBusy, aDevice); + } + else if(CallOnGoing()&& connNum > 1) + { + CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog(CAknNoteDialog::ENoTone, + CAknNoteDialog::ELongTimeout); + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(dlg); + dlg->PublishDialogL(ECmdShowBtImpossibleIncallNote, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(dlg); + } + + dlg->ExecuteLD(R_BT_NOT_INCALL_NOTE); + } + else + { + if(TBTUIViewsCommonUtils::TurnBTOnIfNeededL(iBtEngSettings,iCoverDisplayEnabled)!= KErrNone) + return; + + TInt errorCode = KErrNone; + TBTPowerStateValue currentPowerMode; + errorCode=iBtEngSettings->GetPowerState(currentPowerMode); + + if(errorCode) + { + // handle the error code + return; + } + if ( aNewWaitNote ) + { + // Launch wait note + OpenWaitNoteL(iWaitForConnectDlg,R_BT_CONNECTING_TO_WAIT_NOTE,R_BT_CONNECTING_TO , + ECmdShowBtWaitConnectingToNote,aDevice.iName); + } + iConnectDevice=new(ELeave) TBTDevice(aDevice); + iConnectDevice->iOperation=EOpConnect; + + if( currentPowerMode == EBTPowerOff ) + { + // turn on the flag IsConnectDevice + // + iIsConnectDevice = ETrue; + } + else + { + // connect device + // + iModel->ChangeDevice(*iConnectDevice); + + // reset IsConnectDevice flag + iIsConnectDevice = EFalse; + } + } + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::OpenWaitNoteL +// ---------------------------------------------------------- +void CBTUIPairedDevicesView::OpenWaitNoteL(CAknWaitDialog*& aWaitDialog,TUint aNoteResource,TUint aNoteTextResource, + TSecondaryDisplayBtuiDialogs aSec,const TDesC& aDevName) + { + TRAPD(err, + HBufC* stringholder = StringLoader::LoadLC(aNoteTextResource , aDevName ); + aWaitDialog = new (ELeave) CAknWaitDialog( + reinterpret_cast(&aWaitDialog), ETrue); + aWaitDialog->PrepareLC(aNoteResource); + aWaitDialog->SetTextL(*stringholder); + + if(iCoverDisplayEnabled) + { + aWaitDialog->PublishDialogL( + aSec, KUidCoverUiCategoryBtui); // initializes cover support + CAknMediatorFacade* covercl = AknMediatorFacade(aWaitDialog); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(aDevName);// takes copy so consts are ok too + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + aWaitDialog->SetCallback(this); // for capturing Cancel keypress + aWaitDialog->RunLD(); + + CleanupStack::PopAndDestroy(stringholder); // stringholder + ); + // if the above functions leaves the iWaitNote is deleted, but + // not set to NULL. This will cause a problem, when + // the items may be deleted again, since it has to + // be a member variable, in order to be closed + // programmatically. + if(err!=KErrNone) + { + // that is why we set it to NULL here and + // continue leaving further. + aWaitDialog=NULL; + User::Leave(err); + } + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::LaunchSettingViewL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::LaunchSettingViewL() + { + TRACE_FUNC_ENTRY + + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + + CAknView* settingView = iBTPluginMan->GetSettingViewL(device); + if(settingView != NULL) + { + TUid viewId = settingView->Id(); + if(( device.iStatus & EStatusBtuiConnected) == EStatusBtuiConnected ) + { + TBuf8 DeviceName; + DeviceName.Copy(device.iName); + AppUi()->ActivateLocalViewL( viewId, KNullUid, DeviceName); + } + else + { + AppUi()->ActivateLocalViewL( viewId ); + } + } + else + { + User::Leave(KErrNotFound); + } + + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::DisconnectL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::DisconnectL() + { + TRACE_FUNC_ENTRY + + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + iDisconnectQueryDevice = device;//remember device related with query dialog + + // Create confirmation query + HBufC* stringholder = StringLoader::LoadLC(R_BT_DISCONNECT_FROM, device.iName); + iDisconnectQueryDlg = CAknQueryDialog::NewL(); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(iDisconnectQueryDlg); + iDisconnectQueryDlg->PublishDialogL(ECmdShowDisconnectQuery, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(iDisconnectQueryDlg); + + CAknMediatorFacade* covercl = AknMediatorFacade(iDisconnectQueryDlg); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(device.iName);// takes copy so consts are ok too + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + + TInt keypress = iDisconnectQueryDlg->ExecuteLD(R_BT_DISCONNECT_FROM_QUERY, *stringholder); + + CleanupStack::PopAndDestroy(stringholder); // stringholder + + iDisconnectQueryDlg = NULL; + if(keypress) // User has accepted the dialog + { + device.iOperation = EOpDisconnect; + iModel->ChangeDevice(device); + } + TRACE_FUNC_EXIT + } + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::CancelDisconnectQueryDlgL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::CancelDisconnectQueryDlgL() +{ + TRACE_FUNC_ENTRY + + if(iDisconnectQueryDlg) + { + delete iDisconnectQueryDlg; + iDisconnectQueryDlg = NULL; + } + + TRACE_FUNC_EXIT +} + +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::DisconnectWithoutQuery +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::DisconnectWithoutQuery() +{ + TRACE_FUNC_ENTRY + + TInt index = iContainer->CurrentItemIndex(); + if(index == KErrNotFound) return; + + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + device.iOperation = EOpDisconnect; + iModel->ChangeDevice(device); +} +// ---------------------------------------------------------- +// CBTUIPairedDevicesView::ConnectCompleteL +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::ConnectCompleteL(TInt aError,const TBTDevice& aDevice, + const RBTDevNameArray* aConflictingDeviceNames) + { + TRACE_FUNC_ENTRY + + // Dismiss wait note + // + if(iConnectDevice) + { + delete iConnectDevice; + iConnectDevice=NULL; + } + + if ( iIsPairConnect ) + { + iIsPairConnect = EFalse; + if ( aError != KErrNone && + aError != KErrCancel && + aError != KErrNotSupported && + aError != KErrAlreadyExists && + aError != KErrServerBusy ) + { + // It is possible that we started connecting too soon before the + // device moves to conntable mode from pairing mode. Let's try + // once more: + if ( !iActive ) + { + iActive = CBTUIActive::NewL( + this, KAutoConnect2ndTry, CActive::EPriorityStandard ); + } + iActive->RequestStatus() = KRequestPending; + iActive->GoActive(); + TRequestStatus* stptr = &( iActive->RequestStatus() ); + User::RequestComplete( stptr, KErrNone ); + TRACE_INFO( _L("CBTUIPairedDevicesView, sceadule auto connect 2nd try") ) + return; + } + } + + if(iWaitForConnectDlg) + { + TRACE_INFO(_L("waiting dialog is active, dismiss it")) + iWaitForConnectDlg->ProcessFinishedL(); + } + + switch (aError) + { + case KErrCancel: + TRACE_INFO(_L("aError = KErrCancel")) + break; + case KErrAlreadyExists: // connection exists allready + { + HBufC* stringholder = NULL; + if(aConflictingDeviceNames && aConflictingDeviceNames->Count()> 0) + { + if(aConflictingDeviceNames->Count() == 1) + { + stringholder=StringLoader::LoadLC(R_BT_DISCONNECT_FIRST_PROMPT, + *(*aConflictingDeviceNames)[0],iCoeEnv ); + } + else + { + CPtrC16Array* aa=new(ELeave) CPtrC16Array(1+1); + aa->InsertL(0, *(*aConflictingDeviceNames)[0] ); + aa->InsertL(1, *(*aConflictingDeviceNames)[1] ); + stringholder=StringLoader::LoadLC(R_BT_DISCONNECT_FIRST_STEREO_PROMPT , + *aa,iCoeEnv); + delete(aa); + } + TRACE_INFO(_L("KErrAllreadyExists")) + } + else + { + // Showing a note in this case would always show a note with "%U" in it + // so the note is not shown at all + TRACE_INFO(_L("KErrAlreadyExists, but no device given, not showing a notification")) + break; + } + + CAknInformationNote* note = new (ELeave) CAknInformationNote(); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(note); + note->PublishDialogL(ECmdShowBtDisconnectFirstNote, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(note); + + CAknMediatorFacade* covercl = AknMediatorFacade(note); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + if(aConflictingDeviceNames && aConflictingDeviceNames->Count()> 0) + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(*(*aConflictingDeviceNames)[0]); + } + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + + note->ExecuteLD(*stringholder); + CleanupStack::PopAndDestroy(stringholder); + } + break; + case KErrServerBusy: + { + CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog( + CAknNoteDialog::ENoTone,CAknNoteDialog::ELongTimeout); + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(dlg); + dlg->PublishDialogL(ECmdBtuiShowBtBusyNote, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(dlg); + } + + dlg->ExecuteLD(R_BT_BUSY); + } + break; + case KErrNone: + { + + TRACE_INFO(_L("aError = KErrNone")) + // Create note + // + CAknInformationNote* notePtr = new (ELeave) CAknInformationNote(); + + HBufC* stringHolder = NULL; + + if (!FeatureManager::FeatureSupported(KFeatureIdAccessoryFw)) + { + if (CallOnGoing()) + { + stringHolder = StringLoader::LoadLC(R_BT_AUDIOS_ACCESSORY_PROMPT); // qtn_bt_audio_accessory "Audio routed to BT handsfree" + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(notePtr); + notePtr->PublishDialogL(ECmdBtuiShowBtAudioAccessory, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(notePtr); + } + + notePtr->ExecuteLD(*stringHolder); + } + else + { + TRACE_INFO(_L("No call ongoing. Connected to")) + stringHolder = StringLoader::LoadLC(R_BT_CONF_CONNECTED_PROMPT, aDevice.iName); // "Connected to %U" + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(notePtr); + notePtr->PublishDialogL(ECmdBtuiShowBtConfConnected, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(notePtr); + + CAknMediatorFacade* covercl = AknMediatorFacade(notePtr); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(aDevice.iName); + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + + notePtr->ExecuteLD(*stringHolder); + } + } + else + { + TRACE_INFO(_L("AccFW Supported. Connected to")) + stringHolder = StringLoader::LoadLC(R_BT_CONF_CONNECTED_PROMPT, aDevice.iName); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(notePtr); + notePtr->PublishDialogL(ECmdBtuiShowBtConfConnected, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(notePtr); + + CAknMediatorFacade* covercl = AknMediatorFacade(notePtr); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(aDevice.iName); + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + + notePtr->ExecuteLD(*stringHolder); + } + + CleanupStack::PopAndDestroy(stringHolder); + } + + TRAP_IGNORE(LaunchSettingViewL();) + break; + + case KErrNotSupported: + { + TRACE_INFO(_L("error = KErrNotSupported")) + + + // create note + // + CAknInformationNote* note = new (ELeave) CAknInformationNote(); + HBufC* stringHolder = StringLoader::LoadLC(R_BT_DEVICE_NOT_SUPPORTED,aDevice.iName); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(note); + note->PublishDialogL(ECmdBtuiShowBtDeviceNotSupported, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(note); + + CAknMediatorFacade* covercl = AknMediatorFacade(note); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(aDevice.iName); + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + } + note->ExecuteLD(*stringHolder); + CleanupStack::PopAndDestroy(stringHolder); + } + break; + + default: + { + // Create note + CAknInformationNote* note = new (ELeave) CAknInformationNote(); + HBufC* stringHolder=StringLoader::LoadLC(R_BT_DEVICE_NOT_AVAIL_NOTE ); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(note); + note->PublishDialogL(ECmdBtuiShowBtDeviceNotAvail, KUidCoverUiCategoryBtui); // initializes cover support + CleanupStack::Pop(note); + + } + + note->ExecuteLD(*stringHolder); + CleanupStack::PopAndDestroy(stringHolder); + TRACE_INFO(_L("default error note BT-not-available")) + } + break; + } + TRACE_FUNC_EXIT + } + +// ------------------------------------------------------ +// CBTUIPairedDevicesView::LaunchHelp +// static help launching function for TCallback +// ------------------------------------------------------ +TInt CBTUIPairedDevicesView::LaunchHelp(TAny* aCoeHelpContext) + { +#ifdef __SERIES60_HELP + //TRACE_FUNC_ENTRY + TCoeHelpContext hc; + + if(aCoeHelpContext==NULL) + hc = TCoeHelpContext(KBtuiUid3,KBT_HLP_BLOCKED); + else + hc = *static_cast(aCoeHelpContext); + TRAPD(err, + CArrayFix< TCoeHelpContext >* array=new (ELeave) CArrayFixFlat< TCoeHelpContext >(1); + array->AppendL(hc); + CleanupStack::PushL(array); + // codescan will complain about CCoeEnv::Static(), however it is not reasonable + // avoidable, since this is static funtion. + HlpLauncher::LaunchHelpApplicationL(CCoeEnv::Static()->WsSession() , array); + CleanupStack::Pop(array); + ); + + // the array is not deleted, since deleting it will result + // to E32User-CBase 3. It is assumed that HlpLancher is taking care of it. + // however this has not been documented. + //TRACE_FUNC_EXIT + return err; +#else + return KErrNone; +#endif + } + +// ------------------------------------------------------ +// CBTUIPairedDevicesView::CallOnGoing +// ------------------------------------------------------ +TBool CBTUIPairedDevicesView::CallOnGoing() + { + TRACE_FUNC_ENTRY + TInt callState; + // Try to get the call state property + + TInt err = RProperty::Get(KPSUidCtsyCallInformation, + KCTsyCallState, callState); //KPSUidTelephonyCallInformation should be used // Check also,if retrieving the property value succeeded + return (err == KErrNone) ? + (callState != EPSCTsyCallStateNone && + callState != EPSCTsyCallStateUninitialized) : + EFalse; + } +// ---------------------------------------------------------- +// From MProgressDialogCallback +// CBTUIPairedDevicesView::DialogDismissedL +// +// Cancels pairing/connection operation if user has pressed Cancel softkey. +// Does nothing if the dialog has been dismissed by this program. +// ---------------------------------------------------------- +// +void CBTUIPairedDevicesView::DialogDismissedL(TInt aButtonId ) + { + TRACE_FUNC_ENTRY + + // it was not canceled, but dialog was closed + // because it ended normally, so there is nothing to clean up. + if( aButtonId != EAknSoftkeyCancel ) + return; + + // Cancel ongoing operations if any + // + if ( iWaitForConnectDlg) + { + if( iConnectDevice ) + { + iModel->CancelChange(*iConnectDevice); + delete iConnectDevice; + iConnectDevice=NULL; + iIsPairConnect = EFalse; + } + iWaitForConnectDlg = NULL; + } + if ( iWaitForPairingDlg ) + { + if( iPairingDevice ) + { + TBTDevice device; + device.iAddr = iPairingDevice->BDAddr(); + device.iOperation = EOpPair; + + iDeviceSearcher->CancelSearchRemoteDevice(); + + iModel->CancelChange(device); + + delete iPairingDevice; + iPairingDevice=NULL; + } + // The dialog has already been deleted by UI framework and + // must not be deleted manually. + iWaitForPairingDlg = NULL; + } + + TRACE_FUNC_EXIT + } +// ------------------------------------------------------ +// From MBTEngSdpResultReceiver +// CBTUIPairedDevicesView::ServiceSearchComplete +// not used and implemented as empty +// ------------------------------------------------------ +void CBTUIPairedDevicesView::ServiceSearchComplete(const RSdpRecHandleArray& , TUint , TInt) + { + TRACE_FUNC_ENTRY + } +// ------------------------------------------------------ +// From MBTEngSdpResultReceiver +// CBTUIPairedDevicesView::AttributeSearchComplete +// not used and implemented as empty +// ------------------------------------------------------ +void CBTUIPairedDevicesView::AttributeSearchComplete(TSdpServRecordHandle, + const RSdpResultArray& ,TInt) + { + TRACE_FUNC_ENTRY + } +// ------------------------------------------------------ +// From MBTEngSdpResultReceiver +// CBTUIPairedDevicesView::AttributeSearchComplete +// not used and implemented as empty +// ------------------------------------------------------ +void CBTUIPairedDevicesView::ServiceAttributeSearchComplete(TSdpServRecordHandle , + const RSdpResultArray& ,TInt ) + { + TRACE_FUNC_ENTRY + } +// ------------------------------------------------------ +// From MBTEngSdpResultReceiver +// CBTUIPairedDevicesView::DeviceSearchComplete +// ------------------------------------------------------ +void CBTUIPairedDevicesView::DeviceSearchComplete(CBTDevice* aDevice, TInt aErr) + { + TRACE_FUNC_ENTRY + + TRAPD(err, DeviceSearchCompleteL(aDevice, NULL, aErr); + ); + // something went wrong. + if(err != KErrNone) + { + TRAP_IGNORE( TBTUIViewsCommonUtils::ShowGeneralErrorNoteL(); ); + } + iSearchOngoing=EFalse; + TRACE_FUNC_EXIT + } + +// ------------------------------------------------------ +// From MBTEngSdpResultReceiver +// CBTUIPairedDevicesView::DeviceSearchComplete +// ------------------------------------------------------ +void CBTUIPairedDevicesView::DeviceSearchComplete( CBTDevice* aDevice, + TNameEntry* aNameEntry, TInt aErr ) + { + TRACE_FUNC_ENTRY + + TRAPD(err, DeviceSearchCompleteL(aDevice, aNameEntry, aErr); + ); + // something went wrong. + if(err != KErrNone) + { + TRAP_IGNORE( TBTUIViewsCommonUtils::ShowGeneralErrorNoteL(); ); + } + iSearchOngoing=EFalse; + TRACE_FUNC_EXIT + } + +// ------------------------------------------------------ +// CBTUIPairedDevicesView::DeviceSearchCompleteL +// Leaving version of DeviceSearchComplete +// ------------------------------------------------------ + +void CBTUIPairedDevicesView::DeviceSearchCompleteL(CBTDevice* aDevice, + TNameEntry* aNameEntry, TInt aErr) + { + TRACE_FUNC_ENTRY + iSearchOngoing=EFalse; + if ( !iPairingDevice ) + { + delete iModel; + iModel = NULL; + return; + } + // we must not have multiple pairings at the same time + __ASSERT_DEBUG(aDevice->BDAddr() == iPairingDevice->BDAddr(), + PANIC(EBTPanicTwoPairingAttemptsAtTheSameTime) ); + + // other error condition, most likely dialog cancel. + if(aErr != KErrNone && (aErr != KErrAlreadyExists)) + { + delete iPairingDevice; + iPairingDevice=NULL; + return; + } + + // In case user switches the view fast enough before searching starts, + // It crashes the whole btui by iModel is null value. + // We add an extra check here + // + if ( !iModel ) + { + delete iPairingDevice; + iPairingDevice=NULL; + return; + } + + TBTDevice *tmpDevice=iModel->CreateDeviceL(aDevice, aNameEntry); + CleanupStack::PushL(tmpDevice); + if(tmpDevice->iStatus & (EStatusPhysicallyConnected|EStatusBtuiConnected|EStatusPaired)) + { + ShowDisconnecNoteL(tmpDevice); + CleanupStack::PopAndDestroy(tmpDevice); + delete iPairingDevice; + iPairingDevice=NULL; + return; + } + else + { + // Launch wait note + OpenWaitNoteL(iWaitForPairingDlg,R_BT_WAITING,R_BT_WAITING_PROMPT, + ECmdShowBtWaitingNote,tmpDevice->iName); + + CleanupStack::PopAndDestroy(tmpDevice); + tmpDevice=NULL; + // and start the pairing + iModel->ChangeDevice(aDevice, aNameEntry, EOpPair); + // aDevice is not deleted, since it points to iPairingDevice and it is still used + // after this + } + TRACE_FUNC_EXIT + } +// ------------------------------------------------------ +// CBTUIPairedDevicesView::ShowDisconnecNote +// ------------------------------------------------------ +void CBTUIPairedDevicesView::ShowDisconnecNoteL(TBTDevice *aDevice) + { + HBufC* stringholder = StringLoader::LoadLC( + R_BT_DISCONNECT_FIRST_PROMPT, aDevice->iName); + + // Launch a waiting confirmation note + // + CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote(ETrue); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(note); + note->PublishDialogL(ECmdShowBtSuccesfullyPairedNote, + KUidCoverUiCategoryBtui); // initializes cover support + CAknMediatorFacade* covercl = AknMediatorFacade(note); // uses MOP, so control provided + if (covercl) // returns null if __COVER_DISPLAY is not defined + { + covercl->BufStream() << BTDeviceNameConverter::ToUTF8L(aDevice->iName);// takes copy so consts are ok too + covercl->BufStream().CommitL(); // no more data to send so commit buf + } + CleanupStack::Pop(note); + } + + note->ExecuteLD(*stringholder); + + CleanupStack::PopAndDestroy(stringholder); // stringholder + + } + +void CBTUIPairedDevicesView::ConnectIfNeededAfterPairL( TInt aCount ) + { + TRACE_FUNC_ENTRY + TBTDevice device; + device.iAddr = iPairConnectAddr; + iModel->GetDevice(device); + device.iOperation = EOpConnect; + ConnectL( device, ( aCount ) ? EFalse : ETrue ); + TRACE_FUNC_EXIT + } + +// ------------------------------------------------------ +// CBTUIPairedDevicesView::BondingCompleted +// called by NotifyChangeDeviceComplete +// ------------------------------------------------------ +void CBTUIPairedDevicesView::BondingCompleteL(TInt aError, const TBTDevice& aDevice) + { + TRACE_INFO((_L("aError=%d"), aError)) + // We need to make a copy of the device, since it may be cleaned up + // by device refresh. + TBTDevice bDevice= aDevice; + + // this may look useless, however if the device has a given shortName it is listed with it + // all the time. If you omnit this line it will be shown with its original deviceName, + // dispite it will be listed with the given name + iModel->GetDevice(bDevice); + + delete iPairingDevice; + iPairingDevice=NULL; + + // Dismiss wait note + if(iWaitForPairingDlg) + { + iWaitForPairingDlg->ProcessFinishedL(); + iWaitForPairingDlg = NULL; + } + + // Error handling + switch(aError) + { + case KErrCancel: + break; + case KErrAlreadyExists: // This is a legal return value + case KErrNone: + case KHCIErrorBase: + { + if( (bDevice.iStatus & EStatusConnectable) + && (bDevice.iDeviceClass.MajorDeviceClass() != EMajorDeviceComputer)) + // Only automatically query for a connectable device but not a computer + { + iPairConnectAddr = aDevice.iAddr; + iIsPairConnect = ETrue; + ConnectIfNeededAfterPairL( 0 ); + } + break; + } + default: + { + break; + } + } + TRACE_FUNC_EXIT + } + +// ----------------------------------------------- +// From MBTDeviceObserver +// CBTUIPairedDevicesView::RefreshDeviceList +// calls the container to refresh the deviceList +// ----------------------------------------------- +void CBTUIPairedDevicesView::RefreshDeviceList(const RDeviceArray* aDevices, + TInt aSelectedItemIndex) + { + TRACE_FUNC_ENTRY + TRAPD(err, + if(iContainer) + { + iContainer->RefreshDeviceListL(aDevices,aSelectedItemIndex); + } + ); + if (iActiveMenuPane && iActiveMenuPane->NumberOfItemsInPane()>0 ) + { + TInt index = iContainer->CurrentItemIndex(); + if ( index >=0 ) + { + TBTDevice device; + device.iIndex = index; + iModel->GetDevice(device); + if ( iMenuDevice.iAddr == device.iAddr && + ( ( iMenuDevice.iStatus & EStatusBtuiConnected ) != ( device.iStatus & EStatusBtuiConnected ) ) ) + { + TRACE_INFO(_L("Device status changed, update menupane")); + iMenuDevice = device; + iActiveMenuPane->Close(); + TRAP_IGNORE( this->ProcessCommandL(EAknSoftkeyOptions) ); + } + } + } + if(err!= KErrNone) + { + TRAP_IGNORE( TBTUIViewsCommonUtils::ShowGeneralErrorNoteL(); ); + } + TRACE_FUNC_EXIT + } + + +// ----------------------------------------------- +// +// ----------------------------------------------- +void CBTUIPairedDevicesView::RequestCompletedL( CBTUIActive* aActive, TInt aId, + TInt aStatus ) + { + TRACE_INFO( ( _L("CBTUIPairedDevicesView::RequestCompletedL err %d"), aStatus ) ) + (void) aActive; + (void) aId; + (void) aStatus; + TRACE_INFO( _L("CBTUIPairedDevicesView, auto connect 2nd try ... ") ) + ConnectIfNeededAfterPairL( 1 ); + } + +// ----------------------------------------------- +// +// ----------------------------------------------- +void CBTUIPairedDevicesView::HandleError( CBTUIActive* aActive, TInt aId, + TInt aError ) + { + (void) aActive; + (void) aId; + (void) aError; + iIsPairConnect = EFalse; + } + +// --------------------------------------------------------- +// From MBTDeviceObserver +// CBTUIPairedDevicesView::NotifyChangeDeviceComplete +// This function implement the functionality of command complete. +// The lists of shown devices are refreshed by RefreshDeviceList, +// not by this function +// --------------------------------------------------------- +// +void CBTUIPairedDevicesView::NotifyChangeDeviceComplete(const TInt aErr, + const TBTDevice& aDevice, const RBTDevNameArray* aDevNameArray) + { + TRACE_FUNC_ENTRY + TBTDevice tmpDevice=aDevice; + TRAPD(err,NotifyChangeDeviceCompleteL(aErr,tmpDevice,aDevNameArray + );); + if(err!= KErrNone) + { + TRAP_IGNORE( TBTUIViewsCommonUtils::ShowGeneralErrorNoteL(); ); + } + TRACE_FUNC_EXIT + } +// --------------------------------------------------------- +// CBTUIPairedDevicesView::NotifyChangeDeviceCompleteL +// Leaving version of notifyChangeDevice +// --------------------------------------------------------- + +void CBTUIPairedDevicesView::NotifyChangeDeviceCompleteL(const TInt aErr, + const TBTDevice& aDevice, const RBTDevNameArray* aDevNameArray) + { + TRACE_FUNC_ENTRY + if(iContainer == NULL) return; + + TRACE_INFO((_L("aErr=%d"), aErr)) + TRACE_INFO((_L("aDevice.iOperation=%d"), aDevice.iOperation)) + TRACE_INFO((_L("aDevice.iStatus=%d"), aDevice.iStatus)) + TRACE_INFO((_L("iIsAlreadyConnected=%d"), iIsAlreadyConnected)) + + if (aDevice.iOperation == EOpDisconnect && iExpectedCallBack>0 ) + { + TBTDevice device; + device.iIndex = aDevice.iIndex; + iModel->GetDevice(device); + device.iOperation = EOpUnpair; + iModel->ChangeDevice(device); + iExpectedCallBack--; + } + + if( aDevice.iOperation == EOpConnect ) + { + if( aErr == KErrNone && iIsAlreadyConnected ) + { + TRACE_INFO(_L("Don't show notes several times for the same device with different profile connections")) + return; + } + ConnectCompleteL(aErr, aDevice, aDevNameArray ); + iIsAlreadyConnected = ETrue; + TRACE_INFO(_L("iIsAlreadyConnected False -> True")) + return; + } + if(aDevice.iOperation == EOpPair) + { + BondingCompleteL(aErr, aDevice); + } + if(aErr != KErrNone) + { + // The user tried to rename to a name that allready exists. + if(aDevice.iOperation == EOpChangeName && aErr == KErrAlreadyExists) + { + CAknNoteDialog* dlg2 = new (ELeave) CAknNoteDialog(CAknNoteDialog::EErrorTone, + CAknNoteDialog::ELongTimeout); + dlg2->ExecuteLD(R_BT_NAME_EXISTS_NOTE); + + RenameDeviceDlgL(); + return; + } + // Need to properly handle situation when "Disconnect from xxx" query + // has been shown and paired device has been turned off simultaneously. + // CancelDisconnectQuery dialog need to be closed. + if(aErr == KErrDisconnected) + { + if(iDisconnectQueryDlg && aDevice.iAddr == iDisconnectQueryDevice.iAddr) + CancelDisconnectQueryDlgL(); + + TRACE_FUNC_EXIT + return; + } + // show general error if any of these failed + if( aDevice.iOperation== EOpTrust || + aDevice.iOperation== EOpUntrust || + aDevice.iOperation== EOpBlock || + aDevice.iOperation== EOpChangeName) + { + TBTUIViewsCommonUtils::ShowGeneralErrorNoteL(); + } + return; + } + + if(aDevice.iOperation == EOpUntrust) + { + // Unauthorise ok note, + CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog(CAknNoteDialog::EConfirmationTone, + CAknNoteDialog::ELongTimeout); + + if(iCoverDisplayEnabled) + { + CleanupStack::PushL(dlg); + dlg->PublishDialogL(ECmdShowBtDevSetAsUntrustNote, KUidCoverUiCategoryBtui); + // initializes cover support + CleanupStack::Pop(dlg); + } + dlg->ExecuteLD( R_BT_DEVICE_UNTRUSTED_NOTE ); + } + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------------------------- +// CBTUIPairedDevicesView::CreateTabIconL() +// Creates icon for tab. +// --------------------------------------------------------------------------- +// +CGulIcon* CBTUIPairedDevicesView::CreateTabIconL() + { + TFileName bmpFilename; + bmpFilename += KBitmapFileDrive; + bmpFilename += KDC_APP_BITMAP_DIR; + bmpFilename += KBtuiBmpFileName; + + CGulIcon* icon = AknsUtils::CreateGulIconL( + AknsUtils::SkinInstance(), + KAknsIIDQgnPropBtDevicesTab3, + bmpFilename, + EMbmBtuiQgn_prop_bt_devices_tab3, + EMbmBtuiQgn_prop_bt_devices_tab3_mask ); + + return icon; + } + +// End of File +