--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btui/btuidelegate/btdelegateconnect.cpp Tue Aug 31 15:25:10 2010 +0300
@@ -0,0 +1,288 @@
+/*
+* Copyright (c) 2010 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:
+*
+*/
+
+#include "btdelegateconnect.h"
+#include "btuiutil.h"
+#include "btqtconstants.h"
+#include <QModelIndex>
+#include <hblabel.h>
+#include <btsettingmodel.h>
+#include <btdevicemodel.h>
+#include <hbnotificationdialog.h>
+#include <hbmessagebox.h>
+#include "btuiiconutil.h"
+#include "btdelegatefactory.h"
+#include <bluetoothuitrace.h>
+#include <e32property.h>
+#include <ctsydomainpskeys.h>
+
+BtDelegateConnect::BtDelegateConnect(
+ BtSettingModel* settingModel,
+ BtDeviceModel* deviceModel, QObject *parent) :
+ BtAbstractDelegate(settingModel, deviceModel, parent), mBtengConnMan(0),
+ mAbstractDelegate(0), mActiveHandling(false)
+{
+
+}
+
+BtDelegateConnect::~BtDelegateConnect()
+{
+ delete mBtengConnMan;
+}
+
+/*!
+ * execute connect operation
+ * first check if power is on
+ */
+void BtDelegateConnect::exec( const QVariant ¶ms )
+{
+ if ( mActiveHandling ) {
+ emit commandCompleted( KErrAlreadyExists );
+ return;
+ }
+ mIndex = params.value<QModelIndex>();
+ mActiveHandling = true;
+ // save needed values from model
+ mDeviceName = (mIndex.data(BtDeviceModel::NameAliasRole)).toString();
+ QString addrStr = (mIndex.data(BtDeviceModel::ReadableBdaddrRole)).toString();
+ addrReadbleStringToSymbian( addrStr, mAddr );
+
+ mCod = (mIndex.data(BtDeviceModel::CoDRole)).toInt();
+ mMajorProperty = (mIndex.data(BtDeviceModel::MajorPropertyRole)).toInt();
+
+ // first turn on power if needed
+ if (!isBtPowerOn()) {
+ if (!mAbstractDelegate) //if there is no other delegate running
+ {
+ mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::ManagePower,
+ getSettingModel(), getDeviceModel() );
+ connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(powerDelegateCompleted(int)) );
+ mAbstractDelegate->exec(QVariant(BtPowerOn));
+ }
+ }
+ else {
+ // power is already on
+ exec_connect();
+ }
+}
+
+/*!
+ * power delegate has completed, continue processing
+ */
+void BtDelegateConnect::powerDelegateCompleted(int status)
+{
+ if (mAbstractDelegate)
+ {
+ disconnect(mAbstractDelegate);
+ delete mAbstractDelegate;
+ mAbstractDelegate = 0;
+ }
+ if ( status == KErrNone ) {
+ // continue connecting
+ exec_connect();
+ }
+ else {
+ // error
+ emitCommandComplete(status);
+ }
+}
+
+/*!
+ * execute connect operation
+ */
+void BtDelegateConnect::exec_connect()
+{
+ int error = KErrNone;
+
+ if ( ! mBtengConnMan ){
+ TRAP( error, mBtengConnMan = CBTEngConnMan::NewL(this) );
+ }
+
+ if ( !error ) {
+ TBTDeviceClass btEngDeviceClass(mCod);
+ error = mBtengConnMan->Connect(mAddr, btEngDeviceClass);
+ }
+
+ if( error ) {
+ emitCommandComplete(error);
+ }
+}
+
+/*!
+ * connect callback from CBTengConnMan
+ */
+void BtDelegateConnect::ConnectComplete( TBTDevAddr& aAddr, TInt aErr,
+ RBTDevAddrArray* aConflicts )
+{
+ // It is possible that another audio device has just connected to phone when we are
+ // connecting to this audio device. Or a device is connected while this command
+ // is idle. No handling for these cases.
+ if ( mAddr != aAddr || !mActiveHandling ) {
+ return;
+ }
+
+ // conflict could occur as well if another audio device is already connected
+ // since currently we don't support multiple audio device connections.
+ if ( aErr && aConflicts && aConflicts->Count() ) {
+ // get the display name of the device that is
+ // causing the conflict
+ QString conflictDevAddr;
+ addrSymbianToReadbleString(conflictDevAddr, (*aConflicts)[0] );
+ QModelIndex start = getDeviceModel()->index(0,0);
+ QModelIndexList indexList = getDeviceModel()->match(start, BtDeviceModel::ReadableBdaddrRole, conflictDevAddr);
+ BTUI_ASSERT_X(indexList.count(), "BtDelegateConnect::ConnectComplete()", "device missing from model!");
+ mConflictDevIndex = indexList.at(0);
+
+ // check if conflict device is being used in a call
+ // Note: actually only checking if *any* audio device is involved in a call, not necessarily the
+ // one we are concerned with here. Btaudioman does not currently support finding out the actual
+ // device involved in a call.
+ if (callOngoing()) {
+ HbMessageBox::warning(hbTrId("txt_bt_info_not_possible_during_a_call"));
+ emitCommandComplete(KErrCancel);
+ }
+ else {
+ // no call, check if user wants to disconnect conflict device
+ QString conflictDevName = (mConflictDevIndex.data(BtDeviceModel::NameAliasRole)).toString();
+
+ QString questionText(hbTrId("txt_bt_info_to_connect_1_2_needs_to_be_disconnec")
+ .arg(mDeviceName).arg(conflictDevName));
+
+ HbMessageBox::question( questionText, this, SLOT(handleUserAnswer(int)),
+ HbMessageBox::Continue | HbMessageBox::Cancel );
+ }
+ }
+ else {
+ // command is finished
+ emitCommandComplete(aErr);
+ }
+}
+
+/*!
+ * handle user response to query about disconnecting conflict device
+ */
+void BtDelegateConnect::handleUserAnswer( int answer )
+{
+ if( answer == HbMessageBox::Continue ) {
+ // Continue, ie. disconnect conflict device and then try reconnecting again
+ if (!mAbstractDelegate) //if there is no other delegate running
+ {
+ QList<QVariant>list;
+ QVariant paramFirst;
+ paramFirst.setValue(mConflictDevIndex);
+ QVariant paramSecond(ServiceLevel);
+ list.append(paramFirst);
+ list.append(paramSecond);
+ QVariant paramsList(list);
+ mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::Disconnect,
+ getSettingModel(), getDeviceModel() );
+ connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(disconnectDelegateCompleted(int)) );
+ mAbstractDelegate->exec(paramsList);
+ }
+ }
+ else {
+ // Cancel connect operation
+ emitCommandComplete(KErrCancel);
+ }
+}
+
+/*!
+ * returns true if phone call is ongoing
+ */
+bool BtDelegateConnect::callOngoing()
+{
+ // ToDo: check if there exists Qt PS key for ongoing call
+ int callState;
+ int err = RProperty::Get(KPSUidCtsyCallInformation, KCTsyCallState, callState);
+ if (!err && (callState == EPSCTsyCallStateNone || callState == EPSCTsyCallStateUninitialized)) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+/*!
+ * disconnecting conflict device has completed, continue connecting
+ */
+void BtDelegateConnect::disconnectDelegateCompleted(int status)
+{
+ if (mAbstractDelegate)
+ {
+ disconnect(mAbstractDelegate);
+ delete mAbstractDelegate;
+ mAbstractDelegate = 0;
+ }
+ // finished disconnecting conflict device, now reconnect to original device
+ if ( status == KErrNone ) {
+ exec_connect();
+ }
+ else {
+ // disconnect failed, abort
+ emitCommandComplete( status );
+ }
+}
+
+/*!
+ * not used here
+ */
+void BtDelegateConnect::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr )
+{
+ Q_UNUSED(aAddr);
+ Q_UNUSED(aErr);
+}
+
+/*!
+ * cancel connect operation
+ * ConnectComplete() callback will be called upon completion of cancel with KErrCancel
+ */
+void BtDelegateConnect::cancel()
+{
+ if ( mBtengConnMan ) {
+ mBtengConnMan->CancelConnect(mAddr);
+ }
+}
+
+/*!
+ * shows user notes with connection success/failure information
+ * cancel operation is handled without a user note
+ */
+void BtDelegateConnect::emitCommandComplete(int error)
+{
+ if ( error == KErrNone ) {
+ // success, show indicator with connection status
+
+ HbIcon icon = getBadgedDeviceTypeIcon( mCod, mMajorProperty, BtuiNoCorners);
+ QString str(hbTrId("txt_bt_dpopinfo_connected_to_1"));
+ HbNotificationDialog::launchDialog( icon, hbTrId("txt_bt_dpophead_connected"),
+ str.arg(mDeviceName) );
+ }
+ else if ( error == KErrCancel ) {
+ // no user note, return success since cancel operation completed successfully
+ error = KErrNone;
+ }
+ else {
+ // failure to connect, show user note
+ QString err(hbTrId("txt_bt_info_unable_to_connect_with_bluetooth"));
+ HbMessageBox::warning(err.arg(mDeviceName));
+ }
+ mActiveHandling = false;
+
+ emit commandCompleted(error);
+}
+
+