Symbian: Adjust Creator to work with CODA

Reviewed-by: hjk
This commit is contained in:
Pawel Polanski
2011-01-07 15:47:22 +01:00
parent d5b2954da8
commit 051011bc37
21 changed files with 1386 additions and 273 deletions

View File

@@ -0,0 +1,112 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "ipaddresslineedit.h"
#include <QtGui/QRegExpValidator>
namespace Utils {
// ------------------ IpAddressLineEditPrivate
class IpAddressLineEditPrivate
{
public:
IpAddressLineEditPrivate();
QValidator *m_ipAddressValidator;
QColor m_validColor;
bool m_addressIsValid;
};
IpAddressLineEditPrivate::IpAddressLineEditPrivate() :
m_addressIsValid(true)
{
}
IpAddressLineEdit::IpAddressLineEdit(QWidget* parent) :
QLineEdit(parent),
m_d(new IpAddressLineEditPrivate())
{
m_d->m_validColor = palette().color(QPalette::Text);
const char * ipAddressRegExpPattern = "^\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"
"((:)(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[1-9]\\d{0,3}|0))?$";
QRegExp ipAddressRegExp(ipAddressRegExpPattern);
m_d->m_ipAddressValidator = new QRegExpValidator(ipAddressRegExp, this);
connect(this, SIGNAL(textChanged(QString)), this, SLOT(validateAddress(QString)));
}
IpAddressLineEdit::~IpAddressLineEdit()
{
delete m_d;
}
bool IpAddressLineEdit::isValid() const
{
return m_d->m_addressIsValid;
}
void IpAddressLineEdit::validateAddress(const QString &string)
{
QString copy(string);
int offset(0);
bool isValid = m_d->m_ipAddressValidator->validate(copy, offset) == QValidator::Acceptable;
if (isValid != m_d->m_addressIsValid) {
if (isValid) {
QPalette palette(palette());
palette.setColor(QPalette::Text, m_d->m_validColor);
setPalette(palette);
emit validAddressChanged(copy);
} else {
QPalette palette(palette());
palette.setColor(QPalette::Text, Qt::red);
setPalette(palette);
setToolTip(tr("The IP address is not valid."));
}
m_d->m_addressIsValid = isValid;
} else {
if (isValid)
emit validAddressChanged(copy);
else
emit invalidAddressChanged();
}
}
} // namespace Utils

View File

@@ -0,0 +1,73 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef IPADDRESSLINEEDIT_H
#define IPADDRESSLINEEDIT_H
#include "utils_global.h"
#include <QtGui/QLineEdit>
namespace Utils {
class IpAddressLineEditPrivate;
/**
* A LineEdit widget that validates the IP address inserted.
* The valid address example is 192.168.1.12 or 192.168.1.12:8080
*/
class QTCREATOR_UTILS_EXPORT IpAddressLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit IpAddressLineEdit(QWidget* parent = 0);
virtual ~IpAddressLineEdit();
bool isValid() const;
signals:
void validAddressChanged(const QString& address);
void invalidAddressChanged();
private slots:
void validateAddress(const QString &string);
private:
IpAddressLineEditPrivate *m_d;
};
} // namespace Utils
#endif // IPADDRESSLINEEDIT_H

View File

@@ -54,7 +54,8 @@ SOURCES += $$PWD/environment.cpp \
$$PWD/historycompleter.cpp \ $$PWD/historycompleter.cpp \
$$PWD/buildablehelperlibrary.cpp \ $$PWD/buildablehelperlibrary.cpp \
$$PWD/annotateditemdelegate.cpp \ $$PWD/annotateditemdelegate.cpp \
$$PWD/fileinprojectfinder.cpp $$PWD/fileinprojectfinder.cpp \
$$PWD/ipaddresslineedit.cpp
win32 { win32 {
SOURCES += $$PWD/abstractprocess_win.cpp \ SOURCES += $$PWD/abstractprocess_win.cpp \
@@ -119,7 +120,8 @@ HEADERS += $$PWD/environment.h \
$$PWD/historycompleter.h \ $$PWD/historycompleter.h \
$$PWD/buildablehelperlibrary.h \ $$PWD/buildablehelperlibrary.h \
$$PWD/annotateditemdelegate.h \ $$PWD/annotateditemdelegate.h \
$$PWD/fileinprojectfinder.h $$PWD/fileinprojectfinder.h \
$$PWD/ipaddresslineedit.h
FORMS += $$PWD/filewizardpage.ui \ FORMS += $$PWD/filewizardpage.ui \
$$PWD/projectintropage.ui \ $$PWD/projectintropage.ui \

View File

@@ -51,6 +51,11 @@ namespace Debugger {
class DEBUGGER_EXPORT DebuggerStartParameters class DEBUGGER_EXPORT DebuggerStartParameters
{ {
public: public:
enum CommunicationChannel {
CommunicationChannelTcpIp,
CommunicationChannelUsb
};
DebuggerStartParameters() DebuggerStartParameters()
: isSnapshot(false), : isSnapshot(false),
attachPID(-1), attachPID(-1),
@@ -62,7 +67,9 @@ public:
connParams(Core::SshConnectionParameters::NoProxy), connParams(Core::SshConnectionParameters::NoProxy),
toolChainType(ProjectExplorer::ToolChain_UNKNOWN), toolChainType(ProjectExplorer::ToolChain_UNKNOWN),
startMode(NoStartMode), startMode(NoStartMode),
executableUid(0) executableUid(0),
communicationChannel(CommunicationChannelTcpIp),
serverPort(0)
{} {}
QString executable; QString executable;
@@ -112,6 +119,9 @@ public:
// For Symbian debugging. // For Symbian debugging.
quint32 executableUid; quint32 executableUid;
CommunicationChannel communicationChannel;
QString serverAddress;
quint16 serverPort;
}; };
} // namespace Debugger } // namespace Debugger

View File

@@ -1724,8 +1724,9 @@ AbstractGdbAdapter *GdbEngine::createAdapter()
case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC: case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
case ProjectExplorer::ToolChain_GCCE_GNUPOC: case ProjectExplorer::ToolChain_GCCE_GNUPOC:
// FIXME: 1 of 3 testing hacks. // FIXME: 1 of 3 testing hacks.
if (sp.processArgs.startsWith(__("@tcf@ "))) if (sp.communicationChannel == DebuggerStartParameters::CommunicationChannelTcpIp)
return new TcfTrkGdbAdapter(this); return new TcfTrkGdbAdapter(this);
else
return new TrkGdbAdapter(this); return new TrkGdbAdapter(this);
default: default:
break; break;

View File

@@ -997,7 +997,6 @@ void TcfTrkGdbAdapter::interruptInferior()
void TcfTrkGdbAdapter::startAdapter() void TcfTrkGdbAdapter::startAdapter()
{ {
m_snapshot.fullReset(); m_snapshot.fullReset();
m_session.reset(); m_session.reset();
m_firstResumableExeLoadedEvent = true; m_firstResumableExeLoadedEvent = true;
@@ -1019,17 +1018,10 @@ void TcfTrkGdbAdapter::startAdapter()
if (debug) if (debug)
qDebug() << parameters.processArgs; qDebug() << parameters.processArgs;
// Fixme: 1 of 3 testing hacks.
if (m_remoteArguments.size() < 5 || m_remoteArguments.at(0) != __("@tcf@")) {
m_engine->handleAdapterStartFailed(_("Parameter error"), QString());
return;
}
m_remoteExecutable = m_remoteArguments.at(1); m_uid = parameters.executableUid;
m_uid = m_remoteArguments.at(2).toUInt(0, 16); tcfTrkAddress = QPair<QString, unsigned short>(parameters.serverAddress, parameters.serverPort);
m_symbolFile = m_remoteArguments.at(3); // m_remoteArguments.clear(); FIXME: Should this be here?
tcfTrkAddress = splitIpAddressSpec(m_remoteArguments.at(4), 1534);
m_remoteArguments.clear();
// Unixish gdbs accept only forward slashes // Unixish gdbs accept only forward slashes
m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/')); m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/'));

View File

@@ -58,6 +58,11 @@ const char * const S60_DC_PREFIX("Qt4ProjectManager.S60DeployConfiguration.");
const char * const SERIAL_PORT_NAME_KEY("Qt4ProjectManager.S60DeployConfiguration.SerialPortName"); const char * const SERIAL_PORT_NAME_KEY("Qt4ProjectManager.S60DeployConfiguration.SerialPortName");
const char * const INSTALLATION_DRIVE_LETTER_KEY("Qt4ProjectManager.S60DeployConfiguration.InstallationDriveLetter"); const char * const INSTALLATION_DRIVE_LETTER_KEY("Qt4ProjectManager.S60DeployConfiguration.InstallationDriveLetter");
const char * const SILENT_INSTALL_KEY("Qt4ProjectManager.S60DeployConfiguration.SilentInstall"); const char * const SILENT_INSTALL_KEY("Qt4ProjectManager.S60DeployConfiguration.SilentInstall");
const char * const DEVICE_ADDRESS_KEY("Qt4ProjectManager.S60DeployConfiguration.DeviceAddress");
const char * const DEVICE_PORT_KEY("Qt4ProjectManager.S60DeployConfiguration.DevicePort");
const char * const COMMUNICATION_CHANNEL_KEY("Qt4ProjectManager.S60DeployConfiguration.CommunicationChannel");
const char * const DEFAULT_TCF_TRK_TCP_PORT("65029");
QString pathFromId(const QString &id) QString pathFromId(const QString &id)
{ {
@@ -83,7 +88,9 @@ S60DeployConfiguration::S60DeployConfiguration(Target *parent) :
m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')), m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
#endif #endif
m_installationDrive('C'), m_installationDrive('C'),
m_silentInstall(true) m_silentInstall(true),
m_devicePort(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT)),
m_communicationChannel(CommunicationSerialConnection)
{ {
ctor(); ctor();
} }
@@ -93,7 +100,10 @@ S60DeployConfiguration::S60DeployConfiguration(Target *target, S60DeployConfigur
m_activeBuildConfiguration(0), m_activeBuildConfiguration(0),
m_serialPortName(source->m_serialPortName), m_serialPortName(source->m_serialPortName),
m_installationDrive(source->m_installationDrive), m_installationDrive(source->m_installationDrive),
m_silentInstall(source->m_silentInstall) m_silentInstall(source->m_silentInstall),
m_deviceAddress(source->m_deviceAddress),
m_devicePort(source->m_devicePort),
m_communicationChannel(source->m_communicationChannel)
{ {
ctor(); ctor();
} }
@@ -297,6 +307,9 @@ QVariantMap S60DeployConfiguration::toMap() const
map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName); map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName);
map.insert(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar(m_installationDrive)); map.insert(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar(m_installationDrive));
map.insert(QLatin1String(SILENT_INSTALL_KEY), QVariant(m_silentInstall)); map.insert(QLatin1String(SILENT_INSTALL_KEY), QVariant(m_silentInstall));
map.insert(QLatin1String(DEVICE_ADDRESS_KEY), QVariant(m_deviceAddress));
map.insert(QLatin1String(DEVICE_PORT_KEY), m_devicePort);
map.insert(QLatin1String(COMMUNICATION_CHANNEL_KEY), QVariant(m_communicationChannel));
return map; return map;
} }
@@ -320,6 +333,11 @@ bool S60DeployConfiguration::fromMap(const QVariantMap &map)
m_installationDrive = map.value(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar('C')) m_installationDrive = map.value(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar('C'))
.toChar().toAscii(); .toChar().toAscii();
m_silentInstall = map.value(QLatin1String(SILENT_INSTALL_KEY), QVariant(true)).toBool(); m_silentInstall = map.value(QLatin1String(SILENT_INSTALL_KEY), QVariant(true)).toBool();
m_deviceAddress = map.value(QLatin1String(DEVICE_ADDRESS_KEY)).toString();
m_devicePort = map.value(QLatin1String(DEVICE_PORT_KEY), QString(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT))).toString();
m_communicationChannel = static_cast<CommunicationChannel>(map.value(QLatin1String(COMMUNICATION_CHANNEL_KEY),
QVariant(CommunicationSerialConnection)).toInt());
setDefaultDisplayName(defaultDisplayName()); setDefaultDisplayName(defaultDisplayName());
return true; return true;
} }
@@ -363,6 +381,48 @@ void S60DeployConfiguration::setSilentInstall(bool silent)
m_silentInstall = silent; m_silentInstall = silent;
} }
QString S60DeployConfiguration::deviceAddress() const
{
return m_deviceAddress;
}
void S60DeployConfiguration::setDeviceAddress(const QString &address)
{
if (m_deviceAddress != address) {
m_deviceAddress = address;
emit deviceAddressChanged();
}
}
QString S60DeployConfiguration::devicePort() const
{
return m_devicePort;
}
void S60DeployConfiguration::setDevicePort(const QString &port)
{
if (m_devicePort != port) {
if (port.isEmpty()) //setup the default CODA's port
m_devicePort = QLatin1String(DEFAULT_TCF_TRK_TCP_PORT);
else
m_devicePort = port;
emit devicePortChanged();
}
}
S60DeployConfiguration::CommunicationChannel S60DeployConfiguration::communicationChannel() const
{
return m_communicationChannel;
}
void S60DeployConfiguration::setCommunicationChannel(CommunicationChannel channel)
{
if (m_communicationChannel != channel) {
m_communicationChannel = channel;
emit communicationChannelChanged();
}
}
// ======== S60DeployConfigurationFactory // ======== S60DeployConfigurationFactory
S60DeployConfigurationFactory::S60DeployConfigurationFactory(QObject *parent) : S60DeployConfigurationFactory::S60DeployConfigurationFactory(QObject *parent) :
@@ -402,18 +462,16 @@ DeployConfiguration *S60DeployConfigurationFactory::create(Target *parent, const
bool S60DeployConfigurationFactory::canCreate(Target *parent, const QString& /*id*/) const bool S60DeployConfigurationFactory::canCreate(Target *parent, const QString& /*id*/) const
{ {
Qt4Target * t(qobject_cast<Qt4Target *>(parent)); Qt4Target *t = qobject_cast<Qt4Target *>(parent);
if (!t || if (!t || t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
return false; return false;
return true; return true;
} }
bool S60DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap& /*map*/) const bool S60DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap& /*map*/) const
{ {
Qt4Target * t(qobject_cast<Qt4Target *>(parent)); Qt4Target *t = qobject_cast<Qt4Target *>(parent);
return t && return t && t->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID);
t->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID);
} }
DeployConfiguration *S60DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map) DeployConfiguration *S60DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
@@ -441,6 +499,6 @@ DeployConfiguration *S60DeployConfigurationFactory::clone(Target *parent, Deploy
if (!canClone(parent, source)) if (!canClone(parent, source))
return 0; return 0;
Qt4Target *t = static_cast<Qt4Target *>(parent); Qt4Target *t = static_cast<Qt4Target *>(parent);
S60DeployConfiguration * old(static_cast<S60DeployConfiguration *>(source)); S60DeployConfiguration *old = static_cast<S60DeployConfiguration *>(source);
return new S60DeployConfiguration(t, old); return new S60DeployConfiguration(t, old);
} }

View File

@@ -57,6 +57,11 @@ class S60DeployConfiguration : public ProjectExplorer::DeployConfiguration
friend class S60DeployConfigurationFactory; friend class S60DeployConfigurationFactory;
public: public:
enum CommunicationChannel {
CommunicationSerialConnection,
CommunicationTcpConnection
};
explicit S60DeployConfiguration(ProjectExplorer::Target *parent); explicit S60DeployConfiguration(ProjectExplorer::Target *parent);
virtual ~S60DeployConfiguration(); virtual ~S60DeployConfiguration();
@@ -77,6 +82,15 @@ public:
bool silentInstall() const; bool silentInstall() const;
void setSilentInstall(bool silent); void setSilentInstall(bool silent);
QString deviceAddress() const;
void setDeviceAddress(const QString &address);
void setDevicePort(const QString &port);
QString devicePort() const;
void setCommunicationChannel(CommunicationChannel channel);
S60DeployConfiguration::CommunicationChannel communicationChannel() const;
QStringList signedPackages() const; QStringList signedPackages() const;
QStringList packageFileNamesWithTargetInfo() const; QStringList packageFileNamesWithTargetInfo() const;
QStringList packageTemplateFileNames() const; QStringList packageTemplateFileNames() const;
@@ -87,6 +101,9 @@ public:
signals: signals:
void targetInformationChanged(); void targetInformationChanged();
void serialPortNameChanged(); void serialPortNameChanged();
void communicationChannelChanged();
void deviceAddressChanged();
void devicePortChanged();
private slots: private slots:
void updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration); void updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration);
@@ -113,6 +130,9 @@ private:
char m_installationDrive; char m_installationDrive;
bool m_silentInstall; bool m_silentInstall;
QString m_deviceAddress;
QString m_devicePort;
CommunicationChannel m_communicationChannel;
}; };
class S60DeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory class S60DeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory

View File

@@ -43,6 +43,7 @@
#include <symbianutils/symbiandevicemanager.h> #include <symbianutils/symbiandevicemanager.h>
#include <utils/detailswidget.h> #include <utils/detailswidget.h>
#include <utils/ipaddresslineedit.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
@@ -59,6 +60,9 @@
#include <QtGui/QSpacerItem> #include <QtGui/QSpacerItem>
#include <QtGui/QMessageBox> #include <QtGui/QMessageBox>
#include <QtGui/QCheckBox> #include <QtGui/QCheckBox>
#include <QtGui/QGroupBox>
#include <QtGui/QRadioButton>
#include <QtGui/QValidator>
Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice) Q_DECLARE_METATYPE(SymbianUtils::SymbianDevice)
@@ -77,7 +81,10 @@ S60DeployConfigurationWidget::S60DeployConfigurationWidget(QWidget *parent)
m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))), m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))),
m_deviceInfoLabel(new QLabel), m_deviceInfoLabel(new QLabel),
m_installationDriveCombo(new QComboBox()), m_installationDriveCombo(new QComboBox()),
m_silentInstallCheckBox(new QCheckBox(tr("Silent installation"))) m_silentInstallCheckBox(new QCheckBox(tr("Silent installation"))),
m_serialRadioButton(new QRadioButton(tr("Serial:"))),
m_wlanRadioButton(new QRadioButton(tr("Experimental WLAN:"))), //TODO: Remove ""Experimental" when CODA is stable and official
m_ipAddress(new Utils::IpAddressLineEdit)
{ {
} }
@@ -130,23 +137,8 @@ void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc
updateSerialDevices(); updateSerialDevices();
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()), connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(updated()),
this, SLOT(updateSerialDevices())); this, SLOT(updateSerialDevices()));
// Serial devices control
m_serialPortsCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout;
serialPortHBoxLayout->addWidget(m_serialPortsCombo);
serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
#ifndef Q_OS_WIN formLayout->addRow(createCommunicationChannel());
// Update device list: on Linux only.
QToolButton *updateSerialDevicesButton(new QToolButton);
updateSerialDevicesButton->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload));
connect(updateSerialDevicesButton, SIGNAL(clicked()),
SymbianUtils::SymbianDeviceManager::instance(), SLOT(update()));
serialPortHBoxLayout->addWidget(updateSerialDevicesButton);
#endif
formLayout->addRow(tr("Device on serial port:"), serialPortHBoxLayout);
// Device Info with button. Widgets are enabled in above call to updateSerialDevices() // Device Info with button. Widgets are enabled in above call to updateSerialDevices()
QHBoxLayout *infoHBoxLayout = new QHBoxLayout; QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
@@ -163,6 +155,69 @@ void S60DeployConfigurationWidget::init(ProjectExplorer::DeployConfiguration *dc
this, SLOT(updateTargetInformation())); this, SLOT(updateTargetInformation()));
} }
QWidget *S60DeployConfigurationWidget::createCommunicationChannel()
{
m_serialPortsCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
connect(m_serialRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
connect(m_wlanRadioButton, SIGNAL(clicked()), this, SLOT(updateCommunicationChannel()));
connect(m_ipAddress, SIGNAL(validAddressChanged(QString)), this, SLOT(updateWlanAddress(QString)));
connect(m_ipAddress, SIGNAL(invalidAddressChanged()), this, SLOT(cleanWlanAddress()));
QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout;
serialPortHBoxLayout->addWidget(new QLabel(tr("Serial port:")));
serialPortHBoxLayout->addWidget(m_serialPortsCombo);
serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
#ifndef Q_OS_WIN
// Update device list: on Linux only.
QToolButton *updateSerialDevicesButton(new QToolButton);
updateSerialDevicesButton->setIcon(qApp->style()->standardIcon(QStyle::SP_BrowserReload));
connect(updateSerialDevicesButton, SIGNAL(clicked()),
SymbianUtils::SymbianDeviceManager::instance(), SLOT(update()));
serialPortHBoxLayout->addWidget(updateSerialDevicesButton);
#endif
QGroupBox *communicationChannelGroupBox = new QGroupBox(tr("Communication channel"));
QFormLayout *communicationChannelFormLayout = new QFormLayout();
communicationChannelFormLayout->setWidget(0, QFormLayout::LabelRole, m_serialRadioButton);
communicationChannelFormLayout->setWidget(1, QFormLayout::LabelRole, m_wlanRadioButton);
m_ipAddress->setMinimumWidth(30);
m_ipAddress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
if(!m_deployConfiguration->deviceAddress().isEmpty())
m_ipAddress->setText(QString("%1:%2")
.arg(m_deployConfiguration->deviceAddress())
.arg(m_deployConfiguration->devicePort()));
QHBoxLayout *wlanChannelLayout = new QHBoxLayout();
wlanChannelLayout->addWidget(new QLabel(tr("Address:")));
wlanChannelLayout->addWidget(m_ipAddress);
wlanChannelLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
communicationChannelFormLayout->setLayout(0, QFormLayout::FieldRole, serialPortHBoxLayout);
communicationChannelFormLayout->setLayout(1, QFormLayout::FieldRole, wlanChannelLayout);
switch (m_deployConfiguration->communicationChannel()) {
case S60DeployConfiguration::CommunicationSerialConnection:
m_serialRadioButton->setChecked(true);
m_ipAddress->setDisabled(true);
m_serialPortsCombo->setDisabled(false);
break;
case S60DeployConfiguration::CommunicationTcpConnection:
m_wlanRadioButton->setChecked(true);
m_ipAddress->setDisabled(false);
m_serialPortsCombo->setDisabled(true);
break;
default:
break;
}
communicationChannelGroupBox->setLayout(communicationChannelFormLayout);
return communicationChannelGroupBox;
}
void S60DeployConfigurationWidget::updateInstallationDrives() void S60DeployConfigurationWidget::updateInstallationDrives()
{ {
m_installationDriveCombo->clear(); m_installationDriveCombo->clear();
@@ -244,6 +299,43 @@ void S60DeployConfigurationWidget::setSerialPort(int index)
clearDeviceInfo(); clearDeviceInfo();
} }
void S60DeployConfigurationWidget::updateCommunicationChannel()
{
if (m_serialRadioButton->isChecked()) {
m_ipAddress->setDisabled(true);
m_serialPortsCombo->setDisabled(false);
m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationSerialConnection);
} else if(m_wlanRadioButton->isChecked()) {
QMessageBox::information(this, tr("CODA required"),
tr("You need to have CODA v4.0.14 (or newer) installed on your device "
"in order to use the WLAN functionality.")); //TODO: Remove this when CODA is stable and official
m_ipAddress->setDisabled(false);
m_serialPortsCombo->setDisabled(true);
m_deployConfiguration->setCommunicationChannel(S60DeployConfiguration::CommunicationTcpConnection);
}
}
void S60DeployConfigurationWidget::updateWlanAddress(const QString &address)
{
QStringList addressList = address.split(QLatin1String(":"), QString::SkipEmptyParts);
if (addressList.count() > 0) {
m_deployConfiguration->setDeviceAddress(addressList.at(0));
if (addressList.count() > 1)
m_deployConfiguration->setDevicePort(addressList.at(1));
else
m_deployConfiguration->setDevicePort(QString());
}
}
void S60DeployConfigurationWidget::cleanWlanAddress()
{
if (!m_deployConfiguration->deviceAddress().isEmpty())
m_deployConfiguration->setDeviceAddress(QString());
if (!m_deployConfiguration->devicePort().isEmpty())
m_deployConfiguration->setDevicePort(QString());
}
void S60DeployConfigurationWidget::clearDeviceInfo() void S60DeployConfigurationWidget::clearDeviceInfo()
{ {
// Restore text & color // Restore text & color

View File

@@ -45,10 +45,12 @@ class QLineEdit;
class QComboBox; class QComboBox;
class QToolButton; class QToolButton;
class QCheckBox; class QCheckBox;
class QRadioButton;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { namespace Utils {
class DetailsWidget; class DetailsWidget;
class IpAddressLineEdit;
} }
namespace trk { namespace trk {
@@ -87,6 +89,9 @@ private slots:
void slotLauncherStateChanged(int); void slotLauncherStateChanged(int);
void slotWaitingForTrkClosed(); void slotWaitingForTrkClosed();
void silentInstallChanged(int); void silentInstallChanged(int);
void updateCommunicationChannel();
void updateWlanAddress(const QString &address);
void cleanWlanAddress();
private: private:
inline SymbianUtils::SymbianDevice device(int i) const; inline SymbianUtils::SymbianDevice device(int i) const;
@@ -94,6 +99,8 @@ private:
void setDeviceInfoLabel(const QString &message, bool isError = false); void setDeviceInfoLabel(const QString &message, bool isError = false);
QWidget * createCommunicationChannel();
S60DeployConfiguration *m_deployConfiguration; S60DeployConfiguration *m_deployConfiguration;
Utils::DetailsWidget *m_detailsWidget; Utils::DetailsWidget *m_detailsWidget;
QComboBox *m_serialPortsCombo; QComboBox *m_serialPortsCombo;
@@ -104,6 +111,9 @@ private:
QPointer<trk::Launcher> m_infoLauncher; QPointer<trk::Launcher> m_infoLauncher;
QComboBox *m_installationDriveCombo; QComboBox *m_installationDriveCombo;
QCheckBox *m_silentInstallCheckBox; QCheckBox *m_silentInstallCheckBox;
QRadioButton *m_serialRadioButton;
QRadioButton *m_wlanRadioButton;
Utils::IpAddressLineEdit *m_ipAddress;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -37,6 +37,7 @@
#include "s60deployconfiguration.h" #include "s60deployconfiguration.h"
#include "s60devicerunconfiguration.h" #include "s60devicerunconfiguration.h"
#include "s60runconfigbluetoothstarter.h" #include "s60runconfigbluetoothstarter.h"
#include "tcftrkdevice.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <projectexplorer/buildsteplist.h> #include <projectexplorer/buildsteplist.h>
@@ -47,6 +48,8 @@
#include <symbianutils/launcher.h> #include <symbianutils/launcher.h>
#include <symbianutils/symbiandevicemanager.h> #include <symbianutils/symbiandevicemanager.h>
#include <utils/qtcassert.h>
#include <QtGui/QMessageBox> #include <QtGui/QMessageBox>
#include <QtGui/QMainWindow> #include <QtGui/QMainWindow>
@@ -54,12 +57,20 @@
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QEventLoop> #include <QtCore/QEventLoop>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtNetwork/QTcpSocket>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
enum {debug = 0};
static const quint64 DEFAULT_CHUNK_SIZE = 10240;
namespace { namespace {
const char * const S60_DEPLOY_STEP_ID = "Qt4ProjectManager.S60DeployStep"; const char * const S60_DEPLOY_STEP_ID = "Qt4ProjectManager.S60DeployStep";
} }
static inline bool ensureDeleteFile(const QString &fileName, QString *errorMessage) static inline bool ensureDeleteFile(const QString &fileName, QString *errorMessage)
@@ -95,7 +106,16 @@ S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc,
BuildStep(bc, bs), m_timer(0), BuildStep(bc, bs), m_timer(0),
m_releaseDeviceAfterLauncherFinish(bs->m_releaseDeviceAfterLauncherFinish), m_releaseDeviceAfterLauncherFinish(bs->m_releaseDeviceAfterLauncherFinish),
m_handleDeviceRemoval(bs->m_handleDeviceRemoval), m_handleDeviceRemoval(bs->m_handleDeviceRemoval),
m_launcher(0), m_eventLoop(0) m_launcher(0),
m_trkDevice(0),
m_eventLoop(0),
m_state(StateUninit),
m_putWriteOk(false),
m_putChunkSize(DEFAULT_CHUNK_SIZE),
m_putLastChunkSize(0),
m_currentFileIndex(0),
m_channel(bs->m_channel),
m_deployCanceled(false)
{ {
ctor(); ctor();
} }
@@ -103,7 +123,17 @@ S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc,
S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc): S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc):
BuildStep(bc, QLatin1String(S60_DEPLOY_STEP_ID)), m_timer(0), BuildStep(bc, QLatin1String(S60_DEPLOY_STEP_ID)), m_timer(0),
m_releaseDeviceAfterLauncherFinish(true), m_releaseDeviceAfterLauncherFinish(true),
m_handleDeviceRemoval(true), m_launcher(0), m_eventLoop(0) m_handleDeviceRemoval(true),
m_launcher(0),
m_trkDevice(0),
m_eventLoop(0),
m_state(StateUninit),
m_putWriteOk(false),
m_putChunkSize(DEFAULT_CHUNK_SIZE),
m_putLastChunkSize(0),
m_currentFileIndex(0),
m_channel(S60DeployConfiguration::CommunicationSerialConnection),
m_deployCanceled(false)
{ {
ctor(); ctor();
} }
@@ -118,6 +148,7 @@ S60DeployStep::~S60DeployStep()
{ {
delete m_timer; delete m_timer;
delete m_launcher; delete m_launcher;
delete m_trkDevice;
delete m_eventLoop; delete m_eventLoop;
} }
@@ -125,8 +156,8 @@ S60DeployStep::~S60DeployStep()
bool S60DeployStep::init() bool S60DeployStep::init()
{ {
Qt4BuildConfiguration *bc = static_cast<Qt4BuildConfiguration *>(buildConfiguration()); Qt4BuildConfiguration *bc = static_cast<Qt4BuildConfiguration *>(buildConfiguration());
S60DeployConfiguration* deployConfiguration = static_cast<S60DeployConfiguration *>(bc->target()->activeDeployConfiguration()); S60DeployConfiguration *deployConfiguration = static_cast<S60DeployConfiguration *>(bc->target()->activeDeployConfiguration());
if(!deployConfiguration) if (!deployConfiguration)
return false; return false;
m_serialPortName = deployConfiguration->serialPortName(); m_serialPortName = deployConfiguration->serialPortName();
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName); m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
@@ -135,6 +166,16 @@ bool S60DeployStep::init()
m_installationDrive = deployConfiguration->installationDrive(); m_installationDrive = deployConfiguration->installationDrive();
m_silentInstall = deployConfiguration->silentInstall(); m_silentInstall = deployConfiguration->silentInstall();
switch (deployConfiguration->communicationChannel()) {
case S60DeployConfiguration::CommunicationSerialConnection:
break;
case S60DeployConfiguration::CommunicationTcpConnection:
m_address = deployConfiguration->deviceAddress();
m_port = deployConfiguration->devicePort().toInt();
}
m_channel = deployConfiguration->communicationChannel();
if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
QString message; QString message;
if (m_launcher) { if (m_launcher) {
trk::Launcher::releaseToDeviceManager(m_launcher); trk::Launcher::releaseToDeviceManager(m_launcher);
@@ -151,7 +192,7 @@ bool S60DeployStep::init()
appendMessage(message, true); appendMessage(message, true);
return true; return true;
} }
// Prompt the user to start up the Blue tooth connection // Prompt the user to start up the Bluetooth connection
const trk::PromptStartCommunicationResult src = const trk::PromptStartCommunicationResult src =
S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(), S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
0, &message); 0, &message);
@@ -163,6 +204,7 @@ bool S60DeployStep::init()
appendMessage(message, true); appendMessage(message, true);
return false; return false;
} }
}
return true; return true;
} }
@@ -182,6 +224,16 @@ void S60DeployStep::appendMessage(const QString &error, bool isError)
ProjectExplorer::BuildStep::MessageOutput); ProjectExplorer::BuildStep::MessageOutput);
} }
void S60DeployStep::reportError(const QString &error)
{
emit addOutput(error, ProjectExplorer::BuildStep::ErrorMessageOutput);
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
error,
QString(), -1,
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
emit finished(false);
}
bool S60DeployStep::processPackageName(QString &errorMessage) bool S60DeployStep::processPackageName(QString &errorMessage)
{ {
for (int i = 0; i < m_signedPackages.count(); ++i) { for (int i = 0; i < m_signedPackages.count(); ++i) {
@@ -217,41 +269,49 @@ void S60DeployStep::start()
{ {
QString errorMessage; QString errorMessage;
if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
if (m_serialPortName.isEmpty() || !m_launcher) { if (m_serialPortName.isEmpty() || !m_launcher) {
errorMessage = tr("No device is connected. Please connect a device and try again."); errorMessage = tr("No device is connected. Please connect a device and try again.");
appendMessage(errorMessage, true); reportError(errorMessage);
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
errorMessage,
QString(), -1,
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
emit finished();
return; return;
} }
} else {
QTC_ASSERT(!m_trkDevice, return);
m_trkDevice = new tcftrk::TcfTrkDevice;
if (m_address.isEmpty() || !m_trkDevice) {
errorMessage = tr("No address for a device has been defined. Please define an address and try again.");
reportError(errorMessage);
return;
}
}
// make sure we have the right name of the sis package // make sure we have the right name of the sis package
if (processPackageName(errorMessage)) { if (processPackageName(errorMessage)) {
startDeployment(); startDeployment();
} else { } else {
errorMessage = tr("Failed to find package %1").arg(errorMessage); errorMessage = tr("Failed to find package %1").arg(errorMessage);
appendMessage(errorMessage, true); reportError(errorMessage);
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
errorMessage,
QString(), -1,
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
stop(); stop();
emit finished();
} }
} }
void S60DeployStep::stop() void S60DeployStep::stop()
{ {
if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
if (m_launcher) if (m_launcher)
m_launcher->terminate(); m_launcher->terminate();
emit finished(); } else {
if (m_trkDevice) {
delete m_trkDevice;
m_trkDevice = 0;
}
}
emit finished(false);
} }
void S60DeployStep::setupConnections() void S60DeployStep::setupConnections()
{ {
if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)), connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)),
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice))); this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished())); connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
@@ -265,14 +325,26 @@ void S60DeployStep::setupConnections()
connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(installFailed(QString,QString))); connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(installFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished())); connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished()));
connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int))); connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
} else {
connect(m_trkDevice, SIGNAL(error(QString)), this, SLOT(slotError(QString)));
connect(m_trkDevice, SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(QString)));
connect(m_trkDevice, SIGNAL(tcfEvent(tcftrk::TcfTrkEvent)), this, SLOT(slotTcftrkEvent(tcftrk::TcfTrkEvent)), Qt::DirectConnection);
connect(m_trkDevice, SIGNAL(serialPong(QString)), this, SLOT(slotSerialPong(QString)));
connect(this, SIGNAL(manualInstallation()), this, SLOT(showManualInstallationInfo()));
}
} }
void S60DeployStep::startDeployment() void S60DeployStep::startDeployment()
{ {
Q_ASSERT(m_launcher); if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
QTC_ASSERT(m_launcher, return);
} else {
QTC_ASSERT(m_trkDevice, return);
}
setupConnections(); setupConnections();
if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
QStringList copyDst; QStringList copyDst;
foreach (const QString &signedPackage, m_signedPackages) foreach (const QString &signedPackage, m_signedPackages)
copyDst << QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(QFileInfo(signedPackage).fileName()); copyDst << QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(QFileInfo(signedPackage).fileName());
@@ -291,9 +363,16 @@ void S60DeployStep::startDeployment()
if (!m_launcher->startServer(&errorMessage)) { if (!m_launcher->startServer(&errorMessage)) {
errorMessage = tr("Could not connect to phone on port '%1': %2\n" errorMessage = tr("Could not connect to phone on port '%1': %2\n"
"Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage); "Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
appendMessage(errorMessage, true); reportError(errorMessage);
stop(); stop();
emit finished(); }
} else {
const QSharedPointer<QTcpSocket> tcfTrkSocket(new QTcpSocket);
m_trkDevice->setDevice(tcfTrkSocket);
tcfTrkSocket->connectToHost(m_address, m_port);
m_state = StateConnecting;
appendMessage(tr("Connecting to %1:%2...").arg(m_address).arg(m_port), false);
QTimer::singleShot(4000, this, SLOT(checkForTimeout()));
} }
} }
@@ -301,10 +380,18 @@ void S60DeployStep::run(QFutureInterface<bool> &fi)
{ {
m_futureInterface = &fi; m_futureInterface = &fi;
m_deployResult = true; m_deployResult = true;
connect(this, SIGNAL(finished()), m_deployCanceled = false;
this, SLOT(launcherFinished())); disconnect(this);
connect(this, SIGNAL(finishNow()),
this, SLOT(launcherFinished()), Qt::DirectConnection); if (m_channel == S60DeployConfiguration::CommunicationSerialConnection) {
connect(this, SIGNAL(finished(bool)), this, SLOT(launcherFinished(bool)));
connect(this, SIGNAL(finishNow(bool)), this, SLOT(launcherFinished(bool)), Qt::DirectConnection);
} else {
connect(this, SIGNAL(finished(bool)), this, SLOT(deploymentFinished(bool)));
connect(this, SIGNAL(finishNow(bool)), this, SLOT(deploymentFinished(bool)), Qt::DirectConnection);
connect(this, SIGNAL(allFilesSent()), this, SLOT(startInstalling()), Qt::DirectConnection);
connect(this, SIGNAL(allFilesInstalled()), this, SIGNAL(finished()), Qt::DirectConnection);
}
start(); start();
m_timer = new QTimer(); m_timer = new QTimer();
@@ -316,12 +403,229 @@ void S60DeployStep::run(QFutureInterface<bool> &fi)
delete m_timer; delete m_timer;
m_timer = 0; m_timer = 0;
delete m_trkDevice;
m_trkDevice = 0;
delete m_eventLoop; delete m_eventLoop;
m_eventLoop = 0; m_eventLoop = 0;
fi.reportResult(m_deployResult); fi.reportResult(m_deployResult);
m_futureInterface = 0; m_futureInterface = 0;
} }
void S60DeployStep::slotError(const QString &error)
{
reportError(tr("Error: %1").arg(error));
}
void S60DeployStep::slotTrkLogMessage(const QString &log)
{
if (debug)
qDebug() << "CODA log:" << log;
}
void S60DeployStep::slotSerialPong(const QString &message)
{
if (debug)
qDebug() << "CODA serial pong:" << message;
}
void S60DeployStep::slotTcftrkEvent (const tcftrk::TcfTrkEvent &event)
{
if (debug)
qDebug() << "CODA event:" << "Type:" << event.type() << "Message:" << event.toString();
switch (event.type()) {
case tcftrk::TcfTrkEvent::LocatorHello: {// Commands accepted now
m_state = StateConnected;
emit tcpConnected();
startTransferring();
break;
}
default:
if (debug)
qDebug() << "Unhandled event:" << "Type:" << event.type() << "Message:" << event.toString();
break;
}
}
void S60DeployStep::initFileSending()
{
QTC_ASSERT(m_currentFileIndex < m_signedPackages.count(), return);
QTC_ASSERT(m_currentFileIndex >= 0, return);
const unsigned flags =
tcftrk::TcfTrkDevice::FileSystem_TCF_O_WRITE
|tcftrk::TcfTrkDevice::FileSystem_TCF_O_CREAT
|tcftrk::TcfTrkDevice::FileSystem_TCF_O_TRUNC;
m_putWriteOk = false;
QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
QString remoteFileLocation = QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(packageName);
m_trkDevice->sendFileSystemOpenCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleFileSystemOpen),
remoteFileLocation.toAscii(), flags);
appendMessage(tr("Copying \"%1\"...").arg(packageName), false);
}
void S60DeployStep::initFileInstallation()
{
QTC_ASSERT(m_currentFileIndex < m_signedPackages.count(), return);
QTC_ASSERT(m_currentFileIndex >= 0, return);
QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
QString remoteFileLocation = QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(packageName);
if (m_silentInstall) {
m_trkDevice->sendSymbianInstallSilentInstallCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleSymbianInstall),
remoteFileLocation.toAscii(), QString::fromLatin1("%1:").arg(m_installationDrive).toAscii());
appendMessage(tr("Installing package \"%1\" on drive %2:...").arg(packageName).arg(m_installationDrive), false);
} else {
m_trkDevice->sendSymbianInstallUIInstallCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleSymbianInstall),
remoteFileLocation.toAscii());
appendMessage(tr("Please continue the installation on your device."), false);
emit manualInstallation();
}
}
void S60DeployStep::startTransferring()
{
m_currentFileIndex = 0;
initFileSending();
m_state = StateSendingData;
}
void S60DeployStep::startInstalling()
{
m_currentFileIndex = 0;
initFileInstallation();
m_state = StateInstalling;
}
void S60DeployStep::handleFileSystemOpen(const tcftrk::TcfTrkCommandResult &result)
{
if (result.type != tcftrk::TcfTrkCommandResult::SuccessReply) {
reportError(tr("Open remote file failed: %1").arg(result.errorString()));
return;
}
if (result.values.size() < 1 || result.values.at(0).data().isEmpty()) {
reportError(tr("Internal error: No filehandle obtained"));
return;
}
m_remoteFileHandle = result.values.at(0).data();
m_putFile.reset(new QFile(m_signedPackages.at(m_currentFileIndex)));
if (!m_putFile->open(QIODevice::ReadOnly)) { // Should not fail, was checked before
reportError(tr("Open local file failed: %1").arg(m_putFile->errorString()));
return;
}
putSendNextChunk();
}
void S60DeployStep::handleSymbianInstall(const tcftrk::TcfTrkCommandResult &result)
{
if (result.type == tcftrk::TcfTrkCommandResult::SuccessReply) {
appendMessage(tr("Installation has finished"), false);
if (++m_currentFileIndex >= m_signedPackages.count())
emit allFilesInstalled();
else
initFileInstallation();
} else {
reportError(tr("Installation failed: %1").arg(result.errorString()));
}
}
void S60DeployStep::putSendNextChunk()
{
// Read and send off next chunk
const quint64 pos = m_putFile->pos();
const QByteArray data = m_putFile->read(m_putChunkSize);
if (data.isEmpty()) {
m_putWriteOk = true;
closeRemoteFile();
} else {
m_putLastChunkSize = data.size();
if (debug)
qDebug("Writing %llu bytes to remote file '%s' at %llu\n",
m_putLastChunkSize,
m_remoteFileHandle.constData(), pos);
m_trkDevice->sendFileSystemWriteCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleFileSystemWrite),
m_remoteFileHandle, data, unsigned(pos));
}
}
void S60DeployStep::closeRemoteFile()
{
m_trkDevice->sendFileSystemCloseCommand(tcftrk::TcfTrkCallback(this, &S60DeployStep::handleFileSystemClose),
m_remoteFileHandle);
}
void S60DeployStep::handleFileSystemWrite(const tcftrk::TcfTrkCommandResult &result)
{
// Close remote file even if copy fails
m_putWriteOk = result;
if (!m_putWriteOk) {
QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
reportError(tr("Could not write to file %1 on device: %2").arg(packageName).arg(result.errorString()));
}
if (!m_putWriteOk || m_putLastChunkSize < m_putChunkSize) {
closeRemoteFile();
} else {
putSendNextChunk();
}
}
void S60DeployStep::handleFileSystemClose(const tcftrk::TcfTrkCommandResult &result)
{
if (result.type == tcftrk::TcfTrkCommandResult::SuccessReply) {
if (debug)
qDebug("File closed.\n");
if (++m_currentFileIndex >= m_signedPackages.count())
emit allFilesSent();
else
initFileSending();
} else {
reportError(tr("File close failed: %1").arg(result.toString()));
}
}
void S60DeployStep::checkForTimeout()
{
if (m_state >= StateConnected)
return;
const QString title = tr("Waiting for CODA");
const QString text = tr("Qt Creator is waiting for the CODA application to connect. "
"Please make sure the application is running on "
"your mobile phone and the right ip address and port are "
"configured in the project settings.");
QMessageBox *mb = new QMessageBox(QMessageBox::Information, title, text,
QMessageBox::Cancel, Core::ICore::instance()->mainWindow());
connect(this, SIGNAL(tcpConnected()), mb, SLOT(close()));
connect(this, SIGNAL(finished()), mb, SLOT(close()));
connect(this, SIGNAL(finishNow()), mb, SLOT(close()));
connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTckTrkClosed(int)));
mb->open();
}
void S60DeployStep::showManualInstallationInfo()
{
const QString title = tr("Installation");
const QString text = tr("Please continue the installation on your device.");
QMessageBox *mb = new QMessageBox(QMessageBox::Information, title, text,
QMessageBox::Ok, Core::ICore::instance()->mainWindow());
connect(this, SIGNAL(allFilesInstalled()), mb, SLOT(close()));
connect(this, SIGNAL(finished()), mb, SLOT(close()));
connect(this, SIGNAL(finishNow()), mb, SLOT(close()));
mb->open();
}
void S60DeployStep::slotWaitingForTckTrkClosed(int result)
{
if (result == QMessageBox::Cancel)
m_deployCanceled = true;
}
void S60DeployStep::setReleaseDeviceAfterLauncherFinish(bool v) void S60DeployStep::setReleaseDeviceAfterLauncherFinish(bool v)
{ {
m_releaseDeviceAfterLauncherFinish = v; m_releaseDeviceAfterLauncherFinish = v;
@@ -333,7 +637,7 @@ void S60DeployStep::slotLauncherStateChanged(int s)
QMessageBox *mb = S60DeviceRunControl::createTrkWaitingMessageBox(m_launcher->trkServerName(), QMessageBox *mb = S60DeviceRunControl::createTrkWaitingMessageBox(m_launcher->trkServerName(),
Core::ICore::instance()->mainWindow()); Core::ICore::instance()->mainWindow());
connect(m_launcher, SIGNAL(stateChanged(int)), mb, SLOT(close())); connect(m_launcher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed())); connect(mb, SIGNAL(finished(int)), this, SIGNAL(finished()));
mb->open(); mb->open();
} }
} }
@@ -342,34 +646,29 @@ void S60DeployStep::slotWaitingForTrkClosed()
{ {
if (m_launcher && m_launcher->state() == trk::Launcher::WaitingForTrk) { if (m_launcher && m_launcher->state() == trk::Launcher::WaitingForTrk) {
stop(); stop();
appendMessage(tr("Canceled."), true); reportError(tr("Canceled."));
emit finished();
} }
} }
void S60DeployStep::createFileFailed(const QString &filename, const QString &errorMessage) void S60DeployStep::createFileFailed(const QString &filename, const QString &errorMessage)
{ {
appendMessage(tr("Could not create file %1 on device: %2").arg(filename, errorMessage), true); reportError(tr("Could not create file %1 on device: %2").arg(filename, errorMessage));
m_deployResult = false;
} }
void S60DeployStep::writeFileFailed(const QString &filename, const QString &errorMessage) void S60DeployStep::writeFileFailed(const QString &filename, const QString &errorMessage)
{ {
appendMessage(tr("Could not write to file %1 on device: %2").arg(filename, errorMessage), true); reportError(tr("Could not write to file %1 on device: %2").arg(filename, errorMessage));
m_deployResult = false;
} }
void S60DeployStep::closeFileFailed(const QString &filename, const QString &errorMessage) void S60DeployStep::closeFileFailed(const QString &filename, const QString &errorMessage)
{ {
const QString msg = tr("Could not close file %1 on device: %2. It will be closed when App TRK is closed."); const QString msg = tr("Could not close file %1 on device: %2. It will be closed when App TRK is closed.");
appendMessage( msg.arg(filename, errorMessage), true); reportError( msg.arg(filename, errorMessage));
m_deployResult = false;
} }
void S60DeployStep::connectFailed(const QString &errorMessage) void S60DeployStep::connectFailed(const QString &errorMessage)
{ {
appendMessage(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage), true); reportError(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage));
m_deployResult = false;
} }
void S60DeployStep::printCopyingNotice(const QString &fileName) void S60DeployStep::printCopyingNotice(const QString &fileName)
@@ -389,39 +688,52 @@ void S60DeployStep::printInstallingFinished()
void S60DeployStep::installFailed(const QString &filename, const QString &errorMessage) void S60DeployStep::installFailed(const QString &filename, const QString &errorMessage)
{ {
appendMessage(tr("Could not install from package %1 on device: %2").arg(filename, errorMessage), true); reportError(tr("Could not install from package %1 on device: %2").arg(filename, errorMessage));
m_deployResult = false;
} }
void S60DeployStep::checkForCancel() void S60DeployStep::checkForCancel()
{ {
if (m_futureInterface->isCanceled() && m_timer->isActive()) { if ((m_futureInterface->isCanceled() || m_deployCanceled) && m_timer->isActive()) {
m_timer->stop(); m_timer->stop();
stop(); stop();
appendMessage(tr("Canceled."), true); QString canceledText(tr("Deployment has been cancelled."));
emit finishNow(); appendMessage(canceledText, true);
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
canceledText,
QString(), -1,
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
emit finishNow(false);
} }
} }
void S60DeployStep::launcherFinished() void S60DeployStep::launcherFinished(bool success)
{ {
m_deployResult = success;
if (m_releaseDeviceAfterLauncherFinish && m_launcher) { if (m_releaseDeviceAfterLauncherFinish && m_launcher) {
m_handleDeviceRemoval = false; m_handleDeviceRemoval = false;
trk::Launcher::releaseToDeviceManager(m_launcher); trk::Launcher::releaseToDeviceManager(m_launcher);
} }
if(m_launcher) if (m_launcher)
m_launcher->deleteLater(); m_launcher->deleteLater();
m_launcher = 0; m_launcher = 0;
if(m_eventLoop) if (m_eventLoop)
m_eventLoop->exit();
}
void S60DeployStep::deploymentFinished(bool success)
{
m_deployResult = success;
if (m_trkDevice)
m_trkDevice->deleteLater();
m_trkDevice = 0;
if (m_eventLoop)
m_eventLoop->exit(); m_eventLoop->exit();
} }
void S60DeployStep::deviceRemoved(const SymbianUtils::SymbianDevice &d) void S60DeployStep::deviceRemoved(const SymbianUtils::SymbianDevice &d)
{ {
if (m_handleDeviceRemoval && d.portName() == m_serialPortName) { if (m_handleDeviceRemoval && d.portName() == m_serialPortName)
appendMessage(tr("The device '%1' has been disconnected").arg(d.friendlyName()), true); reportError(tr("The device '%1' has been disconnected").arg(d.friendlyName()));
emit finished();
}
} }
// #pragma mark -- S60DeployStepWidget // #pragma mark -- S60DeployStepWidget

View File

@@ -39,14 +39,22 @@
#include <QtCore/QString> #include <QtCore/QString>
QT_FORWARD_DECLARE_CLASS(QEventLoop) QT_FORWARD_DECLARE_CLASS(QEventLoop)
QT_FORWARD_DECLARE_CLASS(QFile)
namespace SymbianUtils { namespace SymbianUtils {
class SymbianDevice; class SymbianDevice;
} }
namespace trk{ namespace trk{
class Launcher; class Launcher;
} }
namespace tcftrk {
struct TcfTrkCommandResult;
class TcfTrkDevice;
class TcfTrkEvent;
}
namespace ProjectExplorer { namespace ProjectExplorer {
class IOutputParser; class IOutputParser;
} }
@@ -56,6 +64,7 @@ namespace Internal {
class BuildConfiguration; class BuildConfiguration;
class S60DeviceRunConfiguration; class S60DeviceRunConfiguration;
struct CommunicationChannel;
class S60DeployStepFactory : public ProjectExplorer::IBuildStepFactory class S60DeployStepFactory : public ProjectExplorer::IBuildStepFactory
{ {
@@ -111,14 +120,34 @@ private slots:
void printInstallingNotice(const QString &packageName); void printInstallingNotice(const QString &packageName);
void installFailed(const QString &filename, const QString &errorMessage); void installFailed(const QString &filename, const QString &errorMessage);
void printInstallingFinished(); void printInstallingFinished();
void launcherFinished(); void launcherFinished(bool success = true);
void slotLauncherStateChanged(int); void slotLauncherStateChanged(int);
void slotWaitingForTrkClosed(); void slotWaitingForTrkClosed();
void checkForCancel(); void checkForCancel();
void checkForTimeout();
void slotError(const QString &error);
void slotTrkLogMessage(const QString &log);
void slotSerialPong(const QString &message);
void slotTcftrkEvent(const tcftrk::TcfTrkEvent &event);
void startInstalling();
void startTransferring();
void deploymentFinished(bool success);
void slotWaitingForTckTrkClosed(int result);
void showManualInstallationInfo();
signals: signals:
void finished(); void finished(bool success = true);
void finishNow(); void finishNow(bool success = true);
void allFilesSent();
void allFilesInstalled();
void tcpConnected();
void manualInstallation();
private: private:
S60DeployStep(ProjectExplorer::BuildStepList *parent, S60DeployStep(ProjectExplorer::BuildStepList *parent,
@@ -131,11 +160,32 @@ private:
bool processPackageName(QString &errorMessage); bool processPackageName(QString &errorMessage);
void setupConnections(); void setupConnections();
void appendMessage(const QString &error, bool isError); void appendMessage(const QString &error, bool isError);
void reportError(const QString &error);
void handleSymbianInstall(const tcftrk::TcfTrkCommandResult &result);
void handleFileSystemOpen(const tcftrk::TcfTrkCommandResult &result);
void handleFileSystemWrite(const tcftrk::TcfTrkCommandResult &result);
void closeRemoteFile();
void putSendNextChunk();
void handleFileSystemClose(const tcftrk::TcfTrkCommandResult &result);
void initFileSending();
void initFileInstallation();
enum State {
StateUninit,
StateConnecting,
StateConnected,
StateSendingData,
StateInstalling
};
QString m_serialPortName; QString m_serialPortName;
QString m_serialPortFriendlyName; QString m_serialPortFriendlyName;
QStringList m_packageFileNamesWithTarget; // Support for 4.6.1 QStringList m_packageFileNamesWithTarget; // Support for 4.6.1
QStringList m_signedPackages; QStringList m_signedPackages;
QString m_address;
unsigned short m_port;
QTimer *m_timer; QTimer *m_timer;
@@ -145,11 +195,22 @@ private:
QFutureInterface<bool> *m_futureInterface; //not owned QFutureInterface<bool> *m_futureInterface; //not owned
trk::Launcher *m_launcher; trk::Launcher *m_launcher;
tcftrk::TcfTrkDevice *m_trkDevice;
QEventLoop *m_eventLoop; QEventLoop *m_eventLoop;
bool m_deployResult; bool m_deployResult;
char m_installationDrive; char m_installationDrive;
bool m_silentInstall; bool m_silentInstall;
State m_state;
bool m_putWriteOk;
QScopedPointer<QFile> m_putFile;
quint64 m_putLastChunkSize;
QByteArray m_remoteFileHandle;
quint64 m_putChunkSize;
int m_currentFileIndex;
int m_channel;
volatile bool m_deployCanceled;
}; };
class S60DeployStepWidget : public ProjectExplorer::BuildStepConfigWidget class S60DeployStepWidget : public ProjectExplorer::BuildStepConfigWidget

View File

@@ -42,6 +42,9 @@
#include "qt4projectmanagerconstants.h" #include "qt4projectmanagerconstants.h"
#include "qtoutputformatter.h" #include "qtoutputformatter.h"
#include "tcftrkdevice.h"
#include "tcftrkmessage.h"
#include <symbianutils/bluetoothlistener_gui.h> #include <symbianutils/bluetoothlistener_gui.h>
#include <symbianutils/launcher.h> #include <symbianutils/launcher.h>
#include <symbianutils/symbiandevicemanager.h> #include <symbianutils/symbiandevicemanager.h>
@@ -60,9 +63,12 @@
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtNetwork/QTcpSocket>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Qt4ProjectManager; using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
using namespace tcftrk;
namespace { namespace {
@@ -102,7 +108,21 @@ QString pathToId(const QString &path)
return QString::fromLatin1(S60_DEVICE_RC_PREFIX) + path; return QString::fromLatin1(S60_DEVICE_RC_PREFIX) + path;
} }
} // anon namespace bool isProcessRunning(const TcfTrkCommandResult &result, const QString &processName)
{
if (result.values.size() && result.values.at(0).type() == JsonValue::Array) {
foreach(const JsonValue &threadValue, result.values.at(0).children()) {
for (int i = threadValue.children().count()-1; i >= 0; --i) { //Usually our process will be near the end of the list
const JsonValue &value(threadValue.childAt(i));
if (value.hasName("p_name") && QString::fromLatin1(value.data()).startsWith(processName, Qt::CaseInsensitive))
return true;
}
}
}
return false;
}
} // anonymous namespace
// ======== S60DeviceRunConfiguration // ======== S60DeviceRunConfiguration
@@ -495,10 +515,12 @@ RunConfiguration *S60DeviceRunConfigurationFactory::clone(Target *parent, RunCon
S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QString mode) : S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QString mode) :
RunControl(runConfiguration, mode), RunControl(runConfiguration, mode),
m_toolChain(ProjectExplorer::ToolChain_INVALID), m_toolChain(ProjectExplorer::ToolChain_INVALID),
m_launcher(0) m_tcfTrkDevice(0),
m_launcher(0),
m_state(StateUninit)
{ {
// connect for automatically reporting the "finished deploy" state to the progress manager // connect for automatically reporting the "finished deploy" state to the progress manager
connect(this, SIGNAL(finished()), this, SLOT(reportDeployFinished())); connect(this, SIGNAL(finished()), this, SLOT(reportLaunchFinished()));
S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration); S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
const Qt4BuildConfiguration *activeBuildConf = s60runConfig->qt4Target()->activeBuildConfiguration(); const Qt4BuildConfiguration *activeBuildConf = s60runConfig->qt4Target()->activeBuildConfiguration();
@@ -508,6 +530,7 @@ S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QSt
m_toolChain = s60runConfig->toolChainType(); m_toolChain = s60runConfig->toolChainType();
m_serialPortName = activeDeployConf->serialPortName(); m_serialPortName = activeDeployConf->serialPortName();
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName); m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
m_executableUid = s60runConfig->executableUid();
m_targetName = s60runConfig->targetName(); m_targetName = s60runConfig->targetName();
m_commandLineArguments = s60runConfig->commandLineArguments(); m_commandLineArguments = s60runConfig->commandLineArguments();
m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA"); m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA");
@@ -516,13 +539,27 @@ S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QSt
m_qtBinPath = qtv->versionInfo().value(QLatin1String("QT_INSTALL_BINS")); m_qtBinPath = qtv->versionInfo().value(QLatin1String("QT_INSTALL_BINS"));
QTC_ASSERT(!m_qtBinPath.isEmpty(), return); QTC_ASSERT(!m_qtBinPath.isEmpty(), return);
m_executableFileName = s60runConfig->localExecutableFileName(); m_executableFileName = s60runConfig->localExecutableFileName();
switch (activeDeployConf->communicationChannel()) {
case S60DeployConfiguration::CommunicationSerialConnection:
break;
case S60DeployConfiguration::CommunicationTcpConnection:
m_address = activeDeployConf->deviceAddress();
m_port = activeDeployConf->devicePort().toInt();
}
m_useOldTrk = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationSerialConnection;
if (debug) if (debug)
qDebug() << "S60DeviceRunControl::CT" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain) qDebug() << "S60DeviceRunControl::CT" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
<< m_serialPortName; << m_serialPortName << "Use old TRK" << m_useOldTrk;
} }
S60DeviceRunControl::~S60DeviceRunControl() S60DeviceRunControl::~S60DeviceRunControl()
{ {
if (m_tcfTrkDevice) {
m_tcfTrkDevice->deleteLater();
m_tcfTrkDevice = 0;
}
if (m_launcher) { if (m_launcher) {
m_launcher->deleteLater(); m_launcher->deleteLater();
m_launcher = 0; m_launcher = 0;
@@ -539,7 +576,7 @@ void S60DeviceRunControl::start()
m_launchProgress->setProgressValue(0); m_launchProgress->setProgressValue(0);
m_launchProgress->reportStarted(); m_launchProgress->reportStarted();
emit started(); emit started();
if (m_serialPortName.isEmpty()) { if (m_serialPortName.isEmpty() && m_address.isEmpty()) {
m_launchProgress->reportCanceled(); m_launchProgress->reportCanceled();
QString msg = tr("No device is connected. Please connect a device and try again."); QString msg = tr("No device is connected. Please connect a device and try again.");
appendMessage(msg, NormalMessageFormat); appendMessage(msg, NormalMessageFormat);
@@ -568,16 +605,24 @@ void S60DeviceRunControl::start()
RunControl::StopResult S60DeviceRunControl::stop() RunControl::StopResult S60DeviceRunControl::stop()
{ {
if (m_useOldTrk) {
if (m_launcher) if (m_launcher)
m_launcher->terminate(); m_launcher->terminate();
} else {
doStop();
}
return AsynchronousStop; return AsynchronousStop;
} }
bool S60DeviceRunControl::isRunning() const bool S60DeviceRunControl::isRunning() const
{ {
if (m_useOldTrk) {
return m_launcher && (m_launcher->state() == trk::Launcher::Connecting return m_launcher && (m_launcher->state() == trk::Launcher::Connecting
|| m_launcher->state() == trk::Launcher::Connected || m_launcher->state() == trk::Launcher::Connected
|| m_launcher->state() == trk::Launcher::WaitingForTrk); || m_launcher->state() == trk::Launcher::WaitingForTrk);
} else {
return m_tcfTrkDevice && !m_tcfTrkDevice->device().isNull() && m_state >= StateConnecting;
}
} }
void S60DeviceRunControl::startLaunching() void S60DeviceRunControl::startLaunching()
@@ -598,6 +643,25 @@ bool S60DeviceRunControl::setupLauncher(QString &errorMessage)
{ {
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(const SymbianUtils::SymbianDevice)), connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(const SymbianUtils::SymbianDevice)),
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice))); this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
if(!m_useOldTrk) { //FIXME: Remove old TRK
QTC_ASSERT(!m_tcfTrkDevice, return false);
m_tcfTrkDevice = new TcfTrkDevice;
if (debug)
m_tcfTrkDevice->setVerbose(1);
connect(m_tcfTrkDevice, SIGNAL(error(QString)), this, SLOT(slotError(QString)));
connect(m_tcfTrkDevice, SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(QString)));
connect(m_tcfTrkDevice, SIGNAL(tcfEvent(tcftrk::TcfTrkEvent)), this, SLOT(slotTcftrkEvent(tcftrk::TcfTrkEvent)));
connect(m_tcfTrkDevice, SIGNAL(serialPong(QString)), this, SLOT(slotSerialPong(QString)));
const QSharedPointer<QTcpSocket> tcfTrkSocket(new QTcpSocket);
m_tcfTrkDevice->setDevice(tcfTrkSocket);
tcfTrkSocket->connectToHost(m_address, m_port);
m_state = StateConnecting;
appendMessage(tr("Connecting to %1:%2...").arg(m_address).arg(m_port), NormalMessageFormat);
} else {
m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, 0, &errorMessage); m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, 0, &errorMessage);
if (!m_launcher) if (!m_launcher)
return false; return false;
@@ -624,9 +688,187 @@ bool S60DeviceRunControl::setupLauncher(QString &errorMessage)
"Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage); "Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
return false; return false;
} }
}
return true; return true;
} }
void S60DeviceRunControl::doStop()
{
if (!m_tcfTrkDevice) {
finishRunControl();
return;
}
switch (m_state) {
case StateUninit:
case StateConnecting:
case StateConnected:
finishRunControl();
break;
case StateProcessRunning:
QTC_ASSERT(!m_runningProcessId.isEmpty(), return);
m_tcfTrkDevice->sendRunControlTerminateCommand(TcfTrkCallback(),
m_runningProcessId.toAscii());
break;
}
}
void S60DeviceRunControl::slotError(const QString &error)
{
appendMessage(tr("Error: %1").arg(error), ErrorMessageFormat);
finishRunControl();
}
void S60DeviceRunControl::slotTrkLogMessage(const QString &log)
{
if (debug) {
qDebug("CODA log: %s", qPrintable(log.size()>200?log.left(200).append(QLatin1String(" ...")): log));
}
}
void S60DeviceRunControl::slotSerialPong(const QString &message)
{
if (debug)
qDebug() << "CODA serial pong:" << message;
}
void S60DeviceRunControl::slotTcftrkEvent(const TcfTrkEvent &event)
{
if (debug)
qDebug() << "CODA event:" << "Type:" << event.type() << "Message:" << event.toString();
switch (event.type()) {
case TcfTrkEvent::LocatorHello: { // Commands accepted now
m_state = StateConnected;
appendMessage(tr("Connected!"), NormalMessageFormat);
if (m_launchProgress)
m_launchProgress->setProgressValue(PROGRESS_MAX*0.80);
initCommunication();
}
break;
case TcfTrkEvent::RunControlContextRemoved:
handleContextRemoved(event);
break;
case TcfTrkEvent::RunControlContextAdded:
m_state = StateProcessRunning;
reportLaunchFinished();
handleContextAdded(event);
break;
case TcfTrkEvent::RunControlSuspended:
handleContextSuspended(event);
break;
case TcfTrkEvent::RunControlModuleLoadSuspended:
handleModuleLoadSuspended(event);
break;
default:
if (debug)
qDebug() << __FUNCTION__ << "Event not handled" << event.type();
break;
}
}
void S60DeviceRunControl::initCommunication()
{
m_tcfTrkDevice->sendSettingsEnableLogCommand();
m_tcfTrkDevice->sendLoggingAddListenerCommand(TcfTrkCallback(this, &S60DeviceRunControl::handleAddListener));
}
void S60DeviceRunControl::handleContextRemoved(const TcfTrkEvent &event)
{
QVector<QByteArray> &removedItems( static_cast<const TcfTrkRunControlContextRemovedEvent &>(event).ids());
if (!m_runningProcessId.isEmpty()
&& removedItems.contains(m_runningProcessId.toAscii())) {
appendMessage(tr("Process has finished."), NormalMessageFormat);
finishRunControl();
}
}
void S60DeviceRunControl::handleContextAdded(const TcfTrkEvent &event)
{
typedef TcfTrkRunControlContextAddedEvent TcfAddedEvent;
const TcfAddedEvent &me = static_cast<const TcfAddedEvent &>(event);
foreach (const RunControlContext &context, me.contexts()) {
if (context.parentId == "root") //is the created context a process
m_runningProcessId = QLatin1String(context.id);
}
}
void S60DeviceRunControl::handleContextSuspended(const TcfTrkEvent &event)
{
typedef TcfTrkRunControlContextSuspendedEvent TcfSuspendEvent;
const TcfSuspendEvent &me = static_cast<const TcfSuspendEvent &>(event);
switch (me.reason()) {
case TcfSuspendEvent::Crash:
appendMessage(tr("Process has crashed: %1").arg(QString::fromLatin1(me.message())), ErrorMessageFormat);
m_tcfTrkDevice->sendRunControlResumeCommand(TcfTrkCallback(), me.id()); //TODO: Should I resume automaticly
break;
default:
if (debug)
qDebug() << "Context suspend not handled:" << "Reason:" << me.reason() << "Message:" << me.message();
break;
}
}
void S60DeviceRunControl::handleModuleLoadSuspended(const TcfTrkEvent &event)
{
// Debug mode start: Continue:
typedef TcfTrkRunControlModuleLoadContextSuspendedEvent TcfModuleLoadSuspendedEvent;
const TcfModuleLoadSuspendedEvent &me = static_cast<const TcfModuleLoadSuspendedEvent &>(event);
if (me.info().requireResume)
m_tcfTrkDevice->sendRunControlResumeCommand(TcfTrkCallback(), me.id());
}
void S60DeviceRunControl::handleAddListener(const TcfTrkCommandResult &result)
{
if (debug)
qDebug() << __FUNCTION__ <<"Add log listener" << result.toString();
m_tcfTrkDevice->sendSymbianOsDataGetThreadsCommand(TcfTrkCallback(this, &S60DeviceRunControl::handleGetThreads));
}
void S60DeviceRunControl::handleGetThreads(const TcfTrkCommandResult &result)
{
if (isProcessRunning(result, m_targetName)) {
appendMessage(tr("The process is already running on the device. Please first close it."), ErrorMessageFormat);
finishRunControl();
} else {
if (m_launchProgress)
m_launchProgress->setProgressValue(PROGRESS_MAX*0.90);
const QString runFileName = QString::fromLatin1("%1.exe").arg(m_targetName);
m_tcfTrkDevice->sendProcessStartCommand(TcfTrkCallback(this, &S60DeviceRunControl::handleCreateProcess),
runFileName, m_executableUid, m_commandLineArguments.split(" "), QString(), true);
appendMessage(tr("Launching: %1").arg(runFileName), NormalMessageFormat);
}
}
void S60DeviceRunControl::handleCreateProcess(const TcfTrkCommandResult &result)
{
const bool ok = result.type == TcfTrkCommandResult::SuccessReply;
if (ok) {
if (m_launchProgress)
m_launchProgress->setProgressValue(PROGRESS_MAX);
appendMessage(tr("Launched!"), NormalMessageFormat);
} else {
appendMessage(tr("Launch failed: %1").arg(result.toString()), ErrorMessageFormat);
finishRunControl();
}
}
void S60DeviceRunControl::finishRunControl()
{
m_runningProcessId.clear();
if (m_tcfTrkDevice)
m_tcfTrkDevice->deleteLater();
m_tcfTrkDevice = 0;
m_state = StateUninit;
handleRunFinished();
}
//////// Launcher code - to be removed
void S60DeviceRunControl::printConnectFailed(const QString &errorMessage) void S60DeviceRunControl::printConnectFailed(const QString &errorMessage)
{ {
appendMessage(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage), appendMessage(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage),
@@ -638,10 +880,10 @@ void S60DeviceRunControl::launcherFinished()
trk::Launcher::releaseToDeviceManager(m_launcher); trk::Launcher::releaseToDeviceManager(m_launcher);
m_launcher->deleteLater(); m_launcher->deleteLater();
m_launcher = 0; m_launcher = 0;
handleLauncherFinished(); handleRunFinished();
} }
void S60DeviceRunControl::reportDeployFinished() void S60DeviceRunControl::reportLaunchFinished()
{ {
if (m_launchProgress) { if (m_launchProgress) {
m_launchProgress->reportFinished(); m_launchProgress->reportFinished();
@@ -710,13 +952,6 @@ void S60DeviceRunControl::deviceRemoved(const SymbianUtils::SymbianDevice &d)
} }
} }
bool S60DeviceRunControl::checkConfiguration(QString * /* errorMessage */,
QString * /* settingsCategory */,
QString * /* settingsPage */) const
{
return true;
}
void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher *launcher) void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher *launcher)
{ {
connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice())); connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));
@@ -727,12 +962,6 @@ void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher
launcher->setFileName(executable); launcher->setFileName(executable);
} }
void S60DeviceRunControl::handleLauncherFinished()
{
emit finished();
appendMessage(tr("Finished."), NormalMessageFormat);
}
void S60DeviceRunControl::printStartingNotice() void S60DeviceRunControl::printStartingNotice()
{ {
appendMessage(tr("Starting application..."), NormalMessageFormat); appendMessage(tr("Starting application..."), NormalMessageFormat);
@@ -750,6 +979,21 @@ void S60DeviceRunControl::applicationRunFailedNotice(const QString &errorMessage
appendMessage(tr("Could not start application: %1").arg(errorMessage), NormalMessageFormat); appendMessage(tr("Could not start application: %1").arg(errorMessage), NormalMessageFormat);
} }
// End of Launcher code - to be removed
bool S60DeviceRunControl::checkConfiguration(QString * /* errorMessage */,
QString * /* settingsCategory */,
QString * /* settingsPage */) const
{
return true;
}
void S60DeviceRunControl::handleRunFinished()
{
emit finished();
appendMessage(tr("Finished."), NormalMessageFormat);
}
// ======== S60DeviceDebugRunControl // ======== S60DeviceDebugRunControl
// Return symbol file which should co-exist with the executable. // Return symbol file which should co-exist with the executable.
@@ -790,7 +1034,13 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
sp.executable = debugFileName; sp.executable = debugFileName;
sp.executableUid = rc->executableUid(); sp.executableUid = rc->executableUid();
sp.enabledEngines = Debugger::GdbEngineType; sp.enabledEngines = Debugger::GdbEngineType;
sp.serverAddress = activeDeployConf->deviceAddress();
sp.serverPort = activeDeployConf->devicePort().toInt();
//FIXME: there should be only one... trkAdapter
sp.communicationChannel = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationSerialConnection?
Debugger::DebuggerStartParameters::CommunicationChannelUsb:
Debugger::DebuggerStartParameters::CommunicationChannelTcpIp;
QTC_ASSERT(sp.executableUid, return sp); QTC_ASSERT(sp.executableUid, return sp);
// Prefer the '*.sym' file over the '.exe', which should exist at the same // Prefer the '*.sym' file over the '.exe', which should exist at the same

View File

@@ -42,6 +42,8 @@
#include <QtCore/QScopedPointer> #include <QtCore/QScopedPointer>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QTime> //TODO: remove
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMessageBox; class QMessageBox;
class QWidget; class QWidget;
@@ -55,6 +57,13 @@ namespace trk {
class Launcher; class Launcher;
} }
namespace tcftrk {
struct TcfTrkCommandResult;
class TcfTrkDevice;
class TcfTrkEvent;
}
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
class QtVersion; class QtVersion;
class Qt4Target; class Qt4Target;
@@ -154,7 +163,7 @@ public:
protected: protected:
virtual void initLauncher(const QString &executable, trk::Launcher *); virtual void initLauncher(const QString &executable, trk::Launcher *);
virtual void handleLauncherFinished(); virtual void handleRunFinished();
virtual bool checkConfiguration(QString *errorMessage, virtual bool checkConfiguration(QString *errorMessage,
QString *settingsCategory, QString *settingsCategory,
QString *settingsPage) const; QString *settingsPage) const;
@@ -166,7 +175,9 @@ protected slots:
void applicationRunNotice(uint pid); void applicationRunNotice(uint pid);
void applicationRunFailedNotice(const QString &errorMessage); void applicationRunFailedNotice(const QString &errorMessage);
void deviceRemoved(const SymbianUtils::SymbianDevice &); void deviceRemoved(const SymbianUtils::SymbianDevice &);
void reportDeployFinished(); void reportLaunchFinished();
void finishRunControl();
private slots: private slots:
void processStopped(uint pc, uint pid, uint tid, const QString& reason); void processStopped(uint pc, uint pid, uint tid, const QString& reason);
@@ -175,23 +186,58 @@ private slots:
void slotLauncherStateChanged(int); void slotLauncherStateChanged(int);
void slotWaitingForTrkClosed(); void slotWaitingForTrkClosed();
private slots:
void slotError(const QString &error);
void slotTrkLogMessage(const QString &log);
void slotTcftrkEvent(const tcftrk::TcfTrkEvent &event);
void slotSerialPong(const QString &message);
protected: protected:
QFutureInterface<void> *m_launchProgress; QFutureInterface<void> *m_launchProgress;
private: private:
void initCommunication();
void startLaunching(); void startLaunching();
bool setupLauncher(QString &errorMessage); bool setupLauncher(QString &errorMessage);
void doStop();
void handleModuleLoadSuspended(const tcftrk::TcfTrkEvent &event);
void handleContextSuspended(const tcftrk::TcfTrkEvent &event);
void handleContextAdded(const tcftrk::TcfTrkEvent &event);
void handleContextRemoved(const tcftrk::TcfTrkEvent &event);
private:
void handleCreateProcess(const tcftrk::TcfTrkCommandResult &result);
void handleAddListener(const tcftrk::TcfTrkCommandResult &result);
void handleGetThreads(const tcftrk::TcfTrkCommandResult &result);
enum State {
StateUninit,
StateConnecting,
StateConnected,
StateProcessRunning
};
ProjectExplorer::ToolChainType m_toolChain; ProjectExplorer::ToolChainType m_toolChain;
QString m_serialPortName; QString m_serialPortName;
QString m_serialPortFriendlyName; QString m_serialPortFriendlyName;
QString m_address;
unsigned short m_port;
quint32 m_executableUid;
QString m_targetName; QString m_targetName;
QString m_commandLineArguments; QString m_commandLineArguments;
QString m_executableFileName; QString m_executableFileName;
QString m_qtDir; QString m_qtDir;
QString m_qtBinPath; QString m_qtBinPath;
tcftrk::TcfTrkDevice *m_tcfTrkDevice;
trk::Launcher *m_launcher; trk::Launcher *m_launcher;
char m_installationDrive; char m_installationDrive;
QString m_runningProcessId;
State m_state;
bool m_useOldTrk; //FIXME: remove old TRK
}; };
// S60DeviceDebugRunControl starts debugging // S60DeviceDebugRunControl starts debugging

View File

@@ -463,6 +463,12 @@ void Qt4Target::onAddedDeployConfiguration(ProjectExplorer::DeployConfiguration
return; return;
connect(deployConf, SIGNAL(serialPortNameChanged()), connect(deployConf, SIGNAL(serialPortNameChanged()),
this, SLOT(slotUpdateDeviceInformation())); this, SLOT(slotUpdateDeviceInformation()));
connect(deployConf, SIGNAL(communicationChannelChanged()),
this, SLOT(slotUpdateDeviceInformation()));
connect(deployConf, SIGNAL(deviceAddressChanged()),
this, SLOT(slotUpdateDeviceInformation()));
connect(deployConf, SIGNAL(devicePortChanged()),
this, SLOT(slotUpdateDeviceInformation()));
} }
void Qt4Target::slotUpdateDeviceInformation() void Qt4Target::slotUpdateDeviceInformation()
@@ -487,22 +493,16 @@ void Qt4Target::emitProFileEvaluateNeeded()
void Qt4Target::updateToolTipAndIcon() void Qt4Target::updateToolTipAndIcon()
{ {
static const int TARGET_OVERLAY_ORIGINAL_SIZE = 32; static const int TARGET_OVERLAY_ORIGINAL_SIZE = 32;
if (const S60DeployConfiguration *s60DeployConf = qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration())) {
const SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance(); if (qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration())) {
const int deviceIndex = sdm->findByPortName(s60DeployConf->serialPortName());
QPixmap overlay; QPixmap overlay;
if (deviceIndex == -1) { QString tooltip;
setToolTip(tr("<b>Device:</b> Not connected")); if (isSymbianConnectionAvailable(tooltip))
overlay = m_disconnectedPixmap;
} else {
// device connected
const SymbianUtils::SymbianDevice device = sdm->devices().at(deviceIndex);
const QString tooltip = device.additionalInformation().isEmpty() ?
tr("<b>Device:</b> %1").arg(device.friendlyName()) :
tr("<b>Device:</b> %1, %2").arg(device.friendlyName(), device.additionalInformation());
setToolTip(tooltip);
overlay = m_connectedPixmap; overlay = m_connectedPixmap;
} else
overlay = m_disconnectedPixmap;
setToolTip(tooltip);
double factor = Core::Constants::TARGET_ICON_SIZE / (double)TARGET_OVERLAY_ORIGINAL_SIZE; double factor = Core::Constants::TARGET_ICON_SIZE / (double)TARGET_OVERLAY_ORIGINAL_SIZE;
QSize overlaySize(overlay.size().width()*factor, overlay.size().height()*factor); QSize overlaySize(overlay.size().width()*factor, overlay.size().height()*factor);
QPixmap pixmap(Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE); QPixmap pixmap(Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE);
@@ -518,3 +518,40 @@ void Qt4Target::updateToolTipAndIcon()
setOverlayIcon(QIcon()); setOverlayIcon(QIcon());
} }
} }
bool Qt4Target::isSymbianConnectionAvailable(QString &tooltipText)
{
const S60DeployConfiguration *s60DeployConf = qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration());
if (!s60DeployConf)
return false;
switch (s60DeployConf->communicationChannel()) {
case S60DeployConfiguration::CommunicationSerialConnection: {
const SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
const int deviceIndex = sdm->findByPortName(s60DeployConf->serialPortName());
if (deviceIndex == -1) {
tooltipText = tr("<b>Device:</b> Not connected");
return false;
} else {
// device connected
const SymbianUtils::SymbianDevice device = sdm->devices().at(deviceIndex);
tooltipText = device.additionalInformation().isEmpty() ?
tr("<b>Device:</b> %1").arg(device.friendlyName()) :
tr("<b>Device:</b> %1, %2").arg(device.friendlyName(), device.additionalInformation());
return true;
}
}
break;
case S60DeployConfiguration::CommunicationTcpConnection: {
if(!s60DeployConf->deviceAddress().isEmpty() && !s60DeployConf->devicePort().isEmpty()) {
tooltipText = tr("<b>IP address:</b> %1:%2").arg(s60DeployConf->deviceAddress(), s60DeployConf->devicePort());
return true;
}
return false;
}
break;
default:
break;
}
return false;
}

View File

@@ -108,6 +108,9 @@ private slots:
void emitProFileEvaluateNeeded(); void emitProFileEvaluateNeeded();
void updateToolTipAndIcon(); void updateToolTipAndIcon();
private:
bool isSymbianConnectionAvailable(QString &tooltipText);
private: private:
const QPixmap m_connectedPixmap; const QPixmap m_connectedPixmap;
const QPixmap m_disconnectedPixmap; const QPixmap m_disconnectedPixmap;

View File

@@ -932,8 +932,8 @@ void Launcher::installRemotePackage()
void Launcher::handleInstallPackageFinished(const TrkResult &result) void Launcher::handleInstallPackageFinished(const TrkResult &result)
{ {
if (result.errorCode()) { if (result.errorCode()) {
if( installationMode() == InstallationModeSilentAndUser if (installationMode() == InstallationModeSilentAndUser
&& d->m_currentInstallationStep & InstallationModeSilent ) { && d->m_currentInstallationStep & InstallationModeSilent) {
installRemotePackageByUser(); installRemotePackageByUser();
return; return;
} }

View File

@@ -952,11 +952,9 @@ void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
slashPos = binaryIn.lastIndexOf(backSlash); slashPos = binaryIn.lastIndexOf(backSlash);
const QString sysBin = QLatin1String("c:/sys/bin"); const QString sysBin = QLatin1String("c:/sys/bin");
const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1); const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1);
const QString binaryDirectory = slashPos == -1 ? sysBin : binaryIn.left(slashPos);
const QString binary = fixFileName(binaryDirectory + QLatin1Char('/') + binaryFileName);
// Fixup: Does argv[0] convention exist on Symbian? // Fixup: Does argv[0] convention exist on Symbian?
arguments.push_front(binary); arguments.push_front(binaryFileName);
if (workingDirectory.isEmpty()) if (workingDirectory.isEmpty())
workingDirectory = sysBin; workingDirectory = sysBin;
@@ -964,11 +962,11 @@ void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
QByteArray setData; QByteArray setData;
JsonInputStream setStr(setData); JsonInputStream setStr(setData);
setStr << "" << '\0' setStr << "" << '\0'
<< '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ']' << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ',' << "logUserTraces" << ']'
<< '\0' << '[' << '\0' << '['
<< binary << ',' << binaryFileName << ','
<< '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ',' << '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ','
<< additionalLibraries << additionalLibraries << ',' << true
<< ']'; << ']';
sendTcfTrkMessage( sendTcfTrkMessage(
#if 1 #if 1
@@ -980,13 +978,32 @@ void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
QByteArray startData; QByteArray startData;
JsonInputStream startStr(startData); JsonInputStream startStr(startData);
startStr << fixFileName(workingDirectory) startStr << "" //We dont really know the drive of the working dir
<< '\0' << binary << '\0' << arguments << '\0' << '\0' << binaryFileName << '\0' << arguments << '\0'
<< QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard) << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard)
<< debugControl; << debugControl;
sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie); sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie);
} }
void TcfTrkDevice::sendSettingsEnableLogCommand()
{
QByteArray setData;
JsonInputStream setStr(setData);
setStr << "" << '\0'
<< '[' << "logUserTraces" << ']'
<< '\0' << '['
<< true
<< ']';
sendTcfTrkMessage(
#if 1
MessageWithReply, // TCF TRK 4.0.5 onwards
#else
MessageWithoutReply, // TCF TRK 4.0.2
#endif
SettingsService, "set", setData);
}
void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack, void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack,
const QByteArray &id, const QByteArray &id,
const QVariant &cookie) const QVariant &cookie)
@@ -1324,7 +1341,8 @@ void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
value, cookie); value, cookie);
} }
static const char outputListenerIDC[] = "org.eclipse.cdt.debug.edc.ui.ProgramOutputConsoleLogger"; //static const char outputListenerIDC[] = "org.eclipse.cdt.debug.edc.ui.ProgramOutputConsoleLogger";
static const char outputListenerIDC[] = "ProgramOutputConsoleLogger"; //TODO: this one might be the correct one
void TcfTrkDevice::sendLoggingAddListenerCommand(const TcfTrkCallback &callBack, void TcfTrkDevice::sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
const QVariant &cookie) const QVariant &cookie)
@@ -1335,6 +1353,14 @@ void TcfTrkDevice::sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
sendTcfTrkMessage(MessageWithReply, LoggingService, "addListener", data, callBack, cookie); sendTcfTrkMessage(MessageWithReply, LoggingService, "addListener", data, callBack, cookie);
} }
void TcfTrkDevice::sendSymbianOsDataGetThreadsCommand(const TcfTrkCallback &callBack,
const QVariant &cookie)
{
QByteArray data;
sendTcfTrkMessage(MessageWithReply, SymbianOSData, "getThreads", data, callBack, cookie);
}
void tcftrk::TcfTrkDevice::sendFileSystemOpenCommand(const tcftrk::TcfTrkCallback &callBack, void tcftrk::TcfTrkDevice::sendFileSystemOpenCommand(const tcftrk::TcfTrkCallback &callBack,
const QByteArray &name, const QByteArray &name,
unsigned flags, unsigned flags,

View File

@@ -349,6 +349,13 @@ public:
void sendLoggingAddListenerCommand(const TcfTrkCallback &callBack, void sendLoggingAddListenerCommand(const TcfTrkCallback &callBack,
const QVariant &cookie = QVariant()); const QVariant &cookie = QVariant());
// SymbianOs Data
void sendSymbianOsDataGetThreadsCommand(const TcfTrkCallback &callBack,
const QVariant &cookie = QVariant());
// Settings
void sendSettingsEnableLogCommand();
static QByteArray parseMemoryGet(const TcfTrkCommandResult &r); static QByteArray parseMemoryGet(const TcfTrkCommandResult &r);
static QVector<QByteArray> parseRegisterGetChildren(const TcfTrkCommandResult &r); static QVector<QByteArray> parseRegisterGetChildren(const TcfTrkCommandResult &r);
static TcfTrkStatResponse parseStat(const TcfTrkCommandResult &r); static TcfTrkStatResponse parseStat(const TcfTrkCommandResult &r);

View File

@@ -40,7 +40,7 @@
// Names matching the enum // Names matching the enum
static const char *serviceNamesC[] = static const char *serviceNamesC[] =
{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints", { "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints",
"Registers", "Logging", "FileSystem", "SymbianInstall", "Registers", "Logging", "FileSystem", "SymbianInstall", "SymbianOSData",
"UnknownService"}; "UnknownService"};
namespace tcftrk { namespace tcftrk {
@@ -554,7 +554,7 @@ TcfTrkRunControlContextSuspendedEvent::Reason TcfTrkRunControlContextSuspendedEv
if (m_reason == "Breakpoint") if (m_reason == "Breakpoint")
return BreakPoint; return BreakPoint;
// 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific. // 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific.
if (m_reason.contains("exception") || m_reason.contains("panick")) if (m_reason.contains("Exception") || m_reason.contains("panick"))
return Crash; return Crash;
return Other; return Other;
} }

View File

@@ -59,6 +59,7 @@ enum Services {
LoggingService, // non-standard, trk specific LoggingService, // non-standard, trk specific
FileSystemService, FileSystemService,
SymbianInstallService, // non-standard, trk specific SymbianInstallService, // non-standard, trk specific
SymbianOSData, // non-standard, trk specific
UnknownService UnknownService
}; // Note: Check string array 'serviceNamesC' of same size when modifying this. }; // Note: Check string array 'serviceNamesC' of same size when modifying this.