Commit dc006860 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Symbian: Let SymbianDeviceManager handle TrkDevice leases.

...making use of a shared device by all clients. Detect device removal by
delaying the WM_DEVICE event handling. Introduce Acquire/Release mechanism
to SymbianDeviceManager and let acquire() fail if the device is in use, thus
preventing starting 'run' while debugging is active, etc.
Handle "Device removed" (unplugging of cable) signal by closing the device and adding
handlers to the clients, stabilize TrkDevice against it.
Remove communication type from the run configuration parameters (now handled by
SymbianDeviceManager).

Working towards keeping the Trk-connection always open and a giving the target pane
a meaningful tooltip.
For the moment, pass on tooltips from device manager additional information
(Trk version and such as determined by the launcher).
parent ecbb5481
......@@ -33,21 +33,50 @@
#include <windows.h>
#endif
#include <QtDebug>
#include <QtCore/QtDebug>
#include <QtCore/QEvent>
#include <QtCore/QCoreApplication>
using namespace Core::Internal;
namespace Core {
namespace Internal {
EventFilteringMainWindow::EventFilteringMainWindow()
/* The notification signal is delayed by using a custom event
* as otherwise device removal is not detected properly
* (devices are still present in the registry. */
class DeviceNotifyEvent : public QEvent {
public:
explicit DeviceNotifyEvent(int id) : QEvent(static_cast<QEvent::Type>(id)) {}
};
EventFilteringMainWindow::EventFilteringMainWindow() :
m_deviceEventId(QEvent::registerEventType(QEvent::User + 2))
{
}
#ifdef Q_OS_WIN
bool EventFilteringMainWindow::event(QEvent *event)
{
if (event->type() == m_deviceEventId) {
event->accept();
emit deviceChange();
return true;
}
return QMainWindow::event(event);
}
bool EventFilteringMainWindow::winEvent(MSG *msg, long *result)
{
if (msg->message == WM_DEVICECHANGE) {
emit deviceChange();
*result = TRUE;
if (msg->wParam & 0x7 /* DBT_DEVNODES_CHANGED */) {
*result = TRUE;
QCoreApplication::postEvent(this, new DeviceNotifyEvent(m_deviceEventId));
}
}
return false;
}
#endif
} // namespace Internal
} // namespace Core
......@@ -32,6 +32,10 @@
#include <QtGui/QMainWindow>
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
namespace Core {
namespace Internal {
......@@ -46,14 +50,17 @@ class EventFilteringMainWindow : public QMainWindow
public:
EventFilteringMainWindow();
signals:
void deviceChange();
#ifdef Q_OS_WIN
protected:
bool winEvent(MSG *message, long *result);
virtual bool winEvent(MSG *message, long *result);
virtual bool event(QEvent *event);
#endif
signals:
void deviceChange();
private:
const int m_deviceEventId;
};
} // Internal
......
......@@ -224,7 +224,6 @@ const char *DebuggerManager::stateName(int s)
DebuggerStartParameters::DebuggerStartParameters()
: attachPID(-1),
useTerminal(false),
remoteChannelType(-1),
toolChainType(ProjectExplorer::ToolChain::UNKNOWN),
startMode(NoStartMode)
{}
......
......@@ -118,7 +118,6 @@ public:
QString crashParameter; // for AttachCrashedExternal
// for remote debugging
QString remoteChannel;
int remoteChannelType;
QString remoteArchitecture;
QString symbolFileName;
QString serverStartScript;
......
......@@ -31,6 +31,7 @@
#include "bluetoothlistener.h"
#include "debuggermanager.h"
#include "trkoptions.h"
#include "trkdevice.h"
namespace Debugger {
namespace Internal {
......@@ -51,18 +52,16 @@ trk::BluetoothListener *S60DebuggerBluetoothStarter::createListener()
trk::PromptStartCommunicationResult
S60DebuggerBluetoothStarter::startCommunication(const TrkDevicePtr &trkDevice,
int communicationType,
QWidget *msgBoxParent,
QString *errorMessage)
{
// Bluetooth?
if (communicationType == TrkOptions::BlueTooth) {
S60DebuggerBluetoothStarter bluetoothStarter(trkDevice);
return trk::promptStartBluetooth(bluetoothStarter, msgBoxParent, errorMessage);
if (trkDevice->serialFrame()) {
BaseCommunicationStarter serialStarter(trkDevice);
return trk::promptStartSerial(serialStarter, msgBoxParent, errorMessage);
}
// Serial
BaseCommunicationStarter serialStarter(trkDevice);
return trk::promptStartSerial(serialStarter, msgBoxParent, errorMessage);
S60DebuggerBluetoothStarter bluetoothStarter(trkDevice);
return trk::promptStartBluetooth(bluetoothStarter, msgBoxParent, errorMessage);
}
} // namespace Internal
......
......@@ -47,7 +47,6 @@ class S60DebuggerBluetoothStarter : public trk::AbstractBluetoothStarter
public:
static trk::PromptStartCommunicationResult
startCommunication(const TrkDevicePtr &trkDevice,
int communicationType,
QWidget *msgBoxParent,
QString *errorMessage);
......
......@@ -32,6 +32,7 @@
#include "launcher.h"
#include "trkoptions.h"
#include "trkoptionspage.h"
#include "symbiandevicemanager.h"
#include "s60debuggerbluetoothstarter.h"
#include "bluetoothlistener_gui.h"
......@@ -239,9 +240,8 @@ void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
AbstractGdbAdapter(engine),
m_options(options),
m_overrideTrkDeviceType(-1),
m_running(false),
m_trkDevice(new trk::TrkDevice),
m_deviceFromSymbianDeviceManager(false),
m_gdbAckMode(true),
m_verbose(0)
{
......@@ -259,16 +259,8 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
#endif
m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset);
connect(m_trkDevice.data(), SIGNAL(messageReceived(trk::TrkResult)),
this, SLOT(handleTrkResult(trk::TrkResult)));
connect(m_trkDevice.data(), SIGNAL(error(QString)),
this, SLOT(handleTrkError(QString)));
setVerbose(theDebuggerBoolSetting(VerboseLog));
m_trkDevice->setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth);
connect(m_trkDevice.data(), SIGNAL(logMessage(QString)),
this, SLOT(trkLogMessage(QString)));
connect(theDebuggerAction(VerboseLog), SIGNAL(valueChanged(QVariant)),
this, SLOT(setVerbose(QVariant)));
}
......@@ -287,23 +279,8 @@ void TrkGdbAdapter::setVerbose(const QVariant &value)
void TrkGdbAdapter::setVerbose(int verbose)
{
m_verbose = verbose;
m_trkDevice->setVerbose(m_verbose);
}
QString TrkGdbAdapter::effectiveTrkDevice() const
{
if (!m_overrideTrkDevice.isEmpty())
return m_overrideTrkDevice;
if (m_options->mode == TrkOptions::BlueTooth)
return m_options->blueToothDevice;
return m_options->serialPort;
}
int TrkGdbAdapter::effectiveTrkDeviceType() const
{
if (m_overrideTrkDeviceType >= 0)
return m_overrideTrkDeviceType;
return m_options->mode;
if (!m_trkDevice.isNull())
m_trkDevice->setVerbose(m_verbose);
}
void TrkGdbAdapter::trkLogMessage(const QString &msg)
......@@ -1726,14 +1703,66 @@ void TrkGdbAdapter::interruptInferior()
sendTrkMessage(0x1a, TrkCallback(), trkInterruptMessage(), "Interrupting...");
}
void TrkGdbAdapter::trkDeviceRemoved(const SymbianUtils::SymbianDevice &dev)
{
if (state() != DebuggerNotReady && m_deviceFromSymbianDeviceManager
&& !m_trkDevice.isNull() && m_trkDevice->port() == dev.portName()) {
const QString message = QString::fromLatin1("Device '%1' has been disconnected.").arg(dev.friendlyName());
logMessage(message);
emit adapterCrashed(message);
}
}
bool TrkGdbAdapter::initializeDevice(const QString &remoteChannel, QString *errorMessage)
{
m_deviceFromSymbianDeviceManager = false;
if (remoteChannel.isEmpty()) {
// Obtain device from settings page
m_trkDevice = TrkDevicePtr(new TrkDevice);
m_trkDevice->setPort(m_options->mode == TrkOptions::BlueTooth ?
m_options->blueToothDevice : m_options->serialPort);
m_trkDevice->setSerialFrame(m_options->mode != TrkOptions::BlueTooth);
} else {
// Run config: Acquire from device manager.
m_trkDevice = SymbianUtils::SymbianDeviceManager::instance()->acquireDevice(remoteChannel);
if (m_trkDevice.isNull()) {
*errorMessage = tr("Unable to acquire a device on '%1'. It appears to be in use.").arg(remoteChannel);
return false;
}
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(const SymbianUtils::SymbianDevice)),
this, SLOT(trkDeviceRemoved(SymbianUtils::SymbianDevice)));
m_deviceFromSymbianDeviceManager = true;
}
connect(m_trkDevice.data(), SIGNAL(messageReceived(trk::TrkResult)),
this, SLOT(handleTrkResult(trk::TrkResult)));
connect(m_trkDevice.data(), SIGNAL(error(QString)),
this, SLOT(handleTrkError(QString)));
connect(m_trkDevice.data(), SIGNAL(logMessage(QString)),
this, SLOT(trkLogMessage(QString)));
m_trkDevice->setVerbose(m_verbose);
// Prompt the user to start communication
const trk::PromptStartCommunicationResult src =
S60DebuggerBluetoothStarter::startCommunication(m_trkDevice,
0, errorMessage);
switch (src) {
case trk::PromptStartCommunicationConnected:
break;
case trk::PromptStartCommunicationCanceled:
*errorMessage = tr("Canceled");
return false;
case trk::PromptStartCommunicationError:
return false;
}
return true;
}
void TrkGdbAdapter::startAdapter()
{
m_snapshot.fullReset();
// Retrieve parameters
const DebuggerStartParameters &parameters = startParameters();
m_overrideTrkDevice = parameters.remoteChannel;
m_overrideTrkDeviceType = parameters.remoteChannelType;
m_remoteExecutable = parameters.executable;
m_remoteArguments = parameters.processArgs;
m_symbolFile = parameters.symbolFileName;
......@@ -1750,23 +1779,16 @@ void TrkGdbAdapter::startAdapter()
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
logMessage(QLatin1String("### Starting TrkGdbAdapter"));
m_trkDevice->setPort(effectiveTrkDevice());
m_trkDevice->setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth);
// Prompt the user to start communication
QString message;
const trk::PromptStartCommunicationResult src =
S60DebuggerBluetoothStarter::startCommunication(m_trkDevice,
effectiveTrkDeviceType(),
0, &message);
switch (src) {
case trk::PromptStartCommunicationConnected:
break;
case trk::PromptStartCommunicationCanceled:
emit adapterStartFailed(message, QString());
return;
case trk::PromptStartCommunicationError:
emit adapterStartFailed(message, TrkOptionsPage::settingsId());
if (!initializeDevice(parameters.remoteChannel, &message)) {
if (message.isEmpty()) {
emit adapterStartFailed(QString(), QString());
} else {
logMessage(message);
emit adapterStartFailed(message, TrkOptionsPage::settingsId());
}
return;
}
......@@ -2099,7 +2121,16 @@ void TrkGdbAdapter::handleDirectStep3(const TrkResult &result)
void TrkGdbAdapter::cleanup()
{
m_trkDevice->close();
if (!m_trkDevice.isNull()) {
m_trkDevice->close();
if (m_deviceFromSymbianDeviceManager) {
m_trkDevice->disconnect(this);
SymbianUtils::SymbianDeviceManager::instance()->releaseDevice(m_trkDevice->port());
m_deviceFromSymbianDeviceManager = false;
}
m_trkDevice = TrkDevicePtr();
}
delete m_gdbServer;
m_gdbServer = 0;
}
......
......@@ -47,6 +47,9 @@
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
namespace SymbianUtils {
class SymbianDevice;
}
namespace Debugger {
namespace Internal {
......@@ -160,8 +163,6 @@ signals:
private:
const TrkOptionsPtr m_options;
QString m_overrideTrkDevice;
int m_overrideTrkDeviceType;
QString m_gdbServerName; // 127.0.0.1:(2222+uid)
......@@ -180,6 +181,7 @@ public:
private:
void startAdapter();
bool initializeDevice(const QString &remoteChannel, QString *errorMessage);
void startInferior();
void startInferiorPhase2();
void interruptInferior();
......@@ -258,8 +260,10 @@ private:
QByteArray trkStepRangeMessage();
QByteArray trkDeleteProcessMessage();
QByteArray trkInterruptMessage();
Q_SLOT void trkDeviceRemoved(const SymbianUtils::SymbianDevice &);
QSharedPointer<trk::TrkDevice> m_trkDevice;
bool m_deviceFromSymbianDeviceManager;
QString m_adapterFailMessage;
//
......@@ -299,9 +303,6 @@ private:
QHash<int, GdbCommand> m_gdbCookieForToken;
QString effectiveTrkDevice() const;
int effectiveTrkDeviceType() const;
// Debuggee state
trk::Session m_session; // global-ish data (process id, target information)
Snapshot m_snapshot; // local-ish data (memory and registers)
......
......@@ -112,10 +112,8 @@ S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *parent, const QStri
m_cachedTargetInformationValid(false),
#ifdef Q_OS_WIN
m_serialPortName(QLatin1String("COM5")),
m_communicationType(SymbianUtils::SerialPortCommunication),
#else
m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
m_communicationType(SymbianUtils::BlueToothCommunication),
#endif
m_signingMode(SignSelf)
{
......@@ -127,7 +125,6 @@ S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *target, S60DeviceRu
m_proFilePath(source->m_proFilePath),
m_cachedTargetInformationValid(false),
m_serialPortName(source->m_serialPortName),
m_communicationType(source->m_communicationType),
m_signingMode(source->m_signingMode),
m_customSignaturePath(source->m_customSignaturePath),
m_customKeyPath(source->m_customKeyPath)
......@@ -202,7 +199,6 @@ QVariantMap S60DeviceRunConfiguration::toMap() const
map.insert(QLatin1String(CUSTOM_SIGNATURE_PATH_KEY), m_customSignaturePath);
map.insert(QLatin1String(CUSTOM_KEY_PATH_KEY), m_customKeyPath);
map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName);
map.insert(QLatin1String(COMMUNICATION_TYPE_KEY), m_communicationType);
map.insert(QLatin1String(COMMAND_LINE_ARGUMENTS_KEY), m_commandLineArguments);
return map;
......@@ -217,7 +213,6 @@ bool S60DeviceRunConfiguration::fromMap(const QVariantMap &map)
m_customSignaturePath = map.value(QLatin1String(CUSTOM_SIGNATURE_PATH_KEY)).toString();
m_customKeyPath = map.value(QLatin1String(CUSTOM_KEY_PATH_KEY)).toString();
m_serialPortName = map.value(QLatin1String(SERIAL_PORT_NAME_KEY)).toString().trimmed();
m_communicationType = map.value(QLatin1String(COMMUNICATION_TYPE_KEY)).toInt();
m_commandLineArguments = map.value(QLatin1String(COMMAND_LINE_ARGUMENTS_KEY)).toStringList();
return RunConfiguration::fromMap(map);
......@@ -237,16 +232,6 @@ void S60DeviceRunConfiguration::setSerialPortName(const QString &name)
emit serialPortNameChanged();
}
int S60DeviceRunConfiguration::communicationType() const
{
return m_communicationType;
}
void S60DeviceRunConfiguration::setCommunicationType(int t)
{
m_communicationType = t;
}
QString S60DeviceRunConfiguration::targetName() const
{
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
......@@ -485,6 +470,8 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat
m_toolChain(ProjectExplorer::ToolChain::INVALID),
m_makesis(new QProcess(this)),
m_signsis(0),
m_releaseDeviceAfterLauncherFinish(false),
m_handleDeviceRemoval(true),
m_launcher(0)
{
// connect for automatically reporting the "finished deploy" state to the progress manager
......@@ -507,7 +494,6 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat
m_toolChain = s60runConfig->toolChainType();
m_serialPortName = s60runConfig->serialPortName();
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
m_communicationType = s60runConfig->communicationType();
m_targetName = s60runConfig->targetName();
m_baseFileName = s60runConfig->basePackageFilePath();
m_commandLineArguments = s60runConfig->commandLineArguments();
......@@ -553,7 +539,7 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat
m_packageFile = QFileInfo(m_packageFilePath).fileName();
if (debug)
qDebug() << "S60DeviceRunControlBase" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
<< m_serialPortName << m_communicationType << m_workingDirectory;
<< m_serialPortName << m_workingDirectory;
}
S60DeviceRunControlBase::~S60DeviceRunControlBase()
......@@ -564,6 +550,11 @@ S60DeviceRunControlBase::~S60DeviceRunControlBase()
}
}
void S60DeviceRunControlBase::setReleaseDeviceAfterLauncherFinish(bool v)
{
m_releaseDeviceAfterLauncherFinish = v;
}
void S60DeviceRunControlBase::start()
{
m_deployProgress = new QFutureInterface<void>;
......@@ -739,55 +730,59 @@ void S60DeviceRunControlBase::signsisProcessFinished()
}
}
void S60DeviceRunControlBase::startDeployment()
{
m_launcher = new trk::Launcher();
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
connect(m_launcher, SIGNAL(copyingStarted()), this, SLOT(printCopyingNotice()));
connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(printCreateFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(printWriteFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(printCloseFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice()));
connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(printInstallFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished()));
connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int)));
connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
connect(m_launcher, SIGNAL(processStopped(uint,uint,uint,QString)),
this, SLOT(processStopped(uint,uint,uint,QString)));
//TODO sisx destination and file path user definable
m_launcher->setTrkServerName(m_serialPortName);
m_launcher->setSerialFrame(m_communicationType == SymbianUtils::SerialPortCommunication);
if (!m_commandLineArguments.isEmpty())
m_launcher->setCommandLineArgs(m_commandLineArguments);
const QString copySrc(m_baseFileName + ".sisx");
const QString copyDst = QString("C:\\Data\\%1.sisx").arg(QFileInfo(m_baseFileName).fileName());
const QString runFileName = QString("C:\\sys\\bin\\%1.exe").arg(m_targetName);
m_launcher->setCopyFileName(copySrc, copyDst);
m_launcher->setInstallFileName(copyDst);
initLauncher(runFileName, m_launcher);
emit addToOutputWindow(this, tr("Package: %1\nDeploying application to '%2'...").arg(lsFile(copySrc), m_serialPortFriendlyName));
QString errorMessage;
// Prompt the user to start up the Blue tooth connection
const trk::PromptStartCommunicationResult src =
bool success = false;
do {
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(const SymbianUtils::SymbianDevice)),
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, 0, &errorMessage);
if (!m_launcher)
break;
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
connect(m_launcher, SIGNAL(copyingStarted()), this, SLOT(printCopyingNotice()));
connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(printCreateFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(printWriteFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(printCloseFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice()));
connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(printInstallFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished()));
connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int)));
connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
connect(m_launcher, SIGNAL(processStopped(uint,uint,uint,QString)),
this, SLOT(processStopped(uint,uint,uint,QString)));
//TODO sisx destination and file path user definable
if (!m_commandLineArguments.isEmpty())
m_launcher->setCommandLineArgs(m_commandLineArguments);
const QString copySrc(m_baseFileName + QLatin1String(".sisx"));
const QString copyDst = QString::fromLatin1("C:\\Data\\%1.sisx").arg(QFileInfo(m_baseFileName).fileName());
const QString runFileName = QString::fromLatin1("C:\\sys\\bin\\%1.exe").arg(m_targetName);
m_launcher->setCopyFileName(copySrc, copyDst);
m_launcher->setInstallFileName(copyDst);
initLauncher(runFileName, m_launcher);
emit addToOutputWindow(this, tr("Package: %1\nDeploying application to '%2'...").arg(lsFile(copySrc), m_serialPortFriendlyName));
// Prompt the user to start up the Blue tooth connection
const trk::PromptStartCommunicationResult src =
S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
m_communicationType, 0,
&errorMessage);
switch (src) {
case trk::PromptStartCommunicationConnected:
break;
case trk::PromptStartCommunicationCanceled:
case trk::PromptStartCommunicationError:
error(this, errorMessage);
stop();
emit finished();
return;
};
0, &errorMessage);
if (src != trk::PromptStartCommunicationConnected)
break;
if (!m_launcher->startServer(&errorMessage)) {
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);
break;
}
success = true;
} while (false);
if (!m_launcher->startServer(&errorMessage)) {
error(this, 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));
if (!success) {
if (!errorMessage.isEmpty())
error(this, errorMessage);
stop();
emit finished();
}
......@@ -845,6 +840,10 @@ void S60DeviceRunControlBase::printInstallFailed(const QString &filename, const
void S60DeviceRunControlBase::launcherFinished()
{
if (m_releaseDeviceAfterLauncherFinish) {
m_handleDeviceRemoval = false;
trk::Launcher::releaseToDeviceManager(m_launcher);
}
m_launcher->deleteLater();
m_launcher = 0;
handleLauncherFinished();
......@@ -919,6 +918,14 @@ void S60DeviceRunControlBase::printApplicationOutput(const QString &output)
emit addToOutputWindowInline(this, output);
}
void S60DeviceRunControlBase::deviceRemoved(const SymbianUtils::SymbianDevice &d)
{
if (m_handleDeviceRemoval && d.portName() == m_serialPortName) {