diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp index c046d472c07811965114e0daa8b52fe934be76bf..a003657fd012a54e908fff7c5ffdbc512967eeff 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp @@ -1,7 +1,25 @@ #include "maemodeploystep.h" +#include "maemoconstants.h" +#include "maemodeployables.h" #include "maemodeploystepwidget.h" +#include "maemopackagecreationstep.h" +#include "maemorunconfiguration.h" +#include <coreplugin/ssh/sftpchannel.h> +#include <coreplugin/ssh/sshconnection.h> +#include <coreplugin/ssh/sshremoteprocess.h> + +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/target.h> + +#include <QtCore/QCryptographicHash> +#include <QtCore/QEventLoop> +#include <QtCore/QFileInfo> +#include <QtCore/QTimer> + +using namespace Core; using namespace ProjectExplorer; namespace Qt4ProjectManager { @@ -13,11 +31,19 @@ const QLatin1String MaemoDeployStep::Id("Qt4ProjectManager.MaemoDeployStep"); MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc) : BuildStep(bc, Id) { + ctor(); } MaemoDeployStep::MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc, MaemoDeployStep *other) - : BuildStep(bc, other) + : BuildStep(bc, other), m_lastDeployed(other->m_lastDeployed) +{ + ctor(); +} + +MaemoDeployStep::~MaemoDeployStep() {} + +void MaemoDeployStep::ctor() { } @@ -28,12 +54,398 @@ bool MaemoDeployStep::init() void MaemoDeployStep::run(QFutureInterface<bool> &fi) { - fi.reportResult(true); + // Move to GUI thread for connection sharing with run control. + QTimer::singleShot(0, this, SLOT(start())); + + MaemoDeployEventHandler eventHandler(this, fi); } BuildStepConfigWidget *MaemoDeployStep::createConfigWidget() { - return new MaemoDeployStepWidget; + return new MaemoDeployStepWidget(this); +} + +QVariantMap MaemoDeployStep::toMap() const +{ + QVariantMap map(BuildStep::toMap()); + addDeployTimesToMap(map); + return map; +} + +void MaemoDeployStep::addDeployTimesToMap(QVariantMap &map) const +{ + QVariantList hostList; + QVariantList fileList; + QVariantList remotePathList; + QVariantList timeList; + typedef QHash<DeployablePerHost, QDateTime>::ConstIterator DepIt; + for (DepIt it = m_lastDeployed.begin(); it != m_lastDeployed.end(); ++it) { + fileList << it.key().first.localFilePath; + remotePathList << it.key().first.remoteDir; + hostList << it.key().second; + timeList << it.value(); + } + map.insert(LastDeployedHostsKey, hostList); + map.insert(LastDeployedFilesKey, fileList); + map.insert(LastDeployedRemotePathsKey, remotePathList); + map.insert(LastDeployedTimesKey, timeList); +} + +bool MaemoDeployStep::fromMap(const QVariantMap &map) +{ + if (!BuildStep::fromMap(map)) + return false; + getDeployTimesFromMap(map); + return true; +} + +void MaemoDeployStep::getDeployTimesFromMap(const QVariantMap &map) +{ + const QVariantList &hostList = map.value(LastDeployedHostsKey).toList(); + const QVariantList &fileList = map.value(LastDeployedFilesKey).toList(); + const QVariantList &remotePathList + = map.value(LastDeployedRemotePathsKey).toList(); + const QVariantList &timeList = map.value(LastDeployedTimesKey).toList(); + const int elemCount + = qMin(qMin(hostList.size(), fileList.size()), + qMin(remotePathList.size(), timeList.size())); + for (int i = 0; i < elemCount; ++i) { + const MaemoDeployable d(fileList.at(i).toString(), + remotePathList.at(i).toString()); + m_lastDeployed.insert(DeployablePerHost(d, hostList.at(i).toString()), + timeList.at(i).toDateTime()); + } +} + +const MaemoPackageCreationStep *MaemoDeployStep::packagingStep() const +{ + const QList<ProjectExplorer::BuildStep *> &buildSteps + = buildConfiguration()->steps(ProjectExplorer::BuildStep::Deploy); + for (int i = buildSteps.count() - 1; i >= 0; --i) { + const MaemoPackageCreationStep * const pStep + = qobject_cast<MaemoPackageCreationStep *>(buildSteps.at(i)); + if (pStep) + return pStep; + } + Q_ASSERT(!"Impossible: Maemo run configuration without packaging step."); + return 0; +} + +void MaemoDeployStep::raiseError(const QString &errorString) +{ + emit addTask(Task(Task::Error, errorString, QString(), -1, + Constants::TASK_CATEGORY_BUILDSYSTEM)); + stop(); + emit error(); +} + +void MaemoDeployStep::writeOutput(const QString &text, + const QTextCharFormat &format) +{ + emit addOutput(text, format); +} + +void MaemoDeployStep::stop() +{ + if (m_installer && m_installer->isRunning()) { + disconnect(m_installer.data(), 0, this, 0); + } else if (!m_uploadsInProgress.isEmpty() || !m_linksInProgress.isEmpty()) { + m_uploadsInProgress.clear(); + m_linksInProgress.clear(); + m_uploader->closeChannel(); + disconnect(m_uploader.data(), 0, this, 0); + } + if (m_connection) + disconnect(m_connection.data(), 0, this, 0); + m_stopped = true; +} + +QString MaemoDeployStep::uploadDir() const +{ + return homeDirOnDevice(m_connection->connectionParameters().uname); +} + +bool MaemoDeployStep::currentlyNeedsDeployment(const QString &host, + const MaemoDeployable &deployable) const +{ + const QDateTime &lastDeployed + = m_lastDeployed.value(DeployablePerHost(deployable, host)); + return !lastDeployed.isValid() + || QFileInfo(deployable.localFilePath).lastModified() > lastDeployed; +} + +void MaemoDeployStep::setDeployed(const QString &host, + const MaemoDeployable &deployable) +{ + m_lastDeployed.insert(DeployablePerHost(deployable, host), + QDateTime::currentDateTime()); +} + +MaemoDeviceConfig MaemoDeployStep::deviceConfig() const +{ + // TODO: For lib template, get info from config widget + const RunConfiguration * const rc = + buildConfiguration()->target()->activeRunConfiguration(); + return rc ? qobject_cast<const MaemoRunConfiguration *>(rc)->deviceConfig() + : MaemoDeviceConfig(); +} + +QString MaemoDeployStep::packageFileName() const +{ + return QFileInfo(packageFilePath()).fileName(); +} + +QString MaemoDeployStep::packageFilePath() const +{ + return packagingStep()->packageFilePath(); +} + +void MaemoDeployStep::start() +{ + m_stopped = false; + if (m_stopped) + return; + + // TODO: Re-use if possible (disconnect + reconnect). + if (m_connection) + disconnect(m_connection.data(), 0, this, 0); + m_connection = SshConnection::create(); + + const MaemoDeviceConfig &devConfig = deviceConfig(); + if (!devConfig.isValid()) { + raiseError(tr("Deployment failed: No valid device set.")); + return; + } + connect(m_connection.data(), SIGNAL(connected()), this, + SLOT(handleConnected())); + connect(m_connection.data(), SIGNAL(error(SshError)), this, + SLOT(handleConnectionFailure())); + m_connection->connectToHost(devConfig.server); +} + +void MaemoDeployStep::handleConnected() +{ + if (m_stopped) + return; + + // TODO: If nothing to deploy, skip this step. + m_uploader = m_connection->createSftpChannel(); + connect(m_uploader.data(), SIGNAL(initialized()), this, + SLOT(handleSftpChannelInitialized())); + connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this, + SLOT(handleSftpChannelInitializationFailed(QString))); + connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)), + this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString))); + m_uploader->initialize(); +} + +void MaemoDeployStep::handleConnectionFailure() +{ + if (m_stopped) + return; + + raiseError(tr("Could not connect to host: %1") + .arg(m_connection->errorString())); +} + +void MaemoDeployStep::handleSftpChannelInitialized() +{ + if (m_stopped) + return; + + m_uploadsInProgress.clear(); + m_linksInProgress.clear(); + m_needsInstall = false; + const MaemoPackageCreationStep * const pStep = packagingStep(); + const QString hostName = m_connection->connectionParameters().host; + if (pStep->isPackagingEnabled()) { + const MaemoDeployable d(packageFilePath(), uploadDir()); + if (currentlyNeedsDeployment(hostName, d)) { + if (!deploy(MaemoDeployable(d))) + return; + m_needsInstall = true; + } else { + m_needsInstall = false; + } + } else { + const MaemoDeployables * const deployables = pStep->deployables(); + const int deployableCount = deployables->deployableCount(); + for (int i = 0; i < deployableCount; ++i) { + const MaemoDeployable &d = deployables->deployableAt(i); + if (currentlyNeedsDeployment(hostName, d) + && !deploy(MaemoDeployable(d))) + return; + } + m_needsInstall = false; + } + if (m_uploadsInProgress.isEmpty()) + emit done(); +} + +bool MaemoDeployStep::deploy(const MaemoDeployable &deployable) +{ + const QString fileName = QFileInfo(deployable.localFilePath).fileName(); + const QString remoteFilePath = deployable.remoteDir + '/' + fileName; + const QString uploadFilePath = uploadDir() + '/' + fileName + '.' + + QCryptographicHash::hash(remoteFilePath.toUtf8(), + QCryptographicHash::Md5).toHex(); + const SftpJobId job = m_uploader->uploadFile(deployable.localFilePath, + uploadFilePath, SftpOverwriteExisting); + if (job == SftpInvalidJob) { + raiseError(tr("Upload failed: Could not open file '%1'") + .arg(deployable.localFilePath)); + return false; + } + writeOutput(tr("Started uploading file '%1'.").arg(deployable.localFilePath)); + m_uploadsInProgress.insert(job, DeployInfo(deployable, uploadFilePath)); + return true; +} + +void MaemoDeployStep::handleSftpChannelInitializationFailed(const QString &error) +{ + if (m_stopped) + return; + raiseError(tr("Could not set up SFTP connection: %1").arg(error)); +} + +void MaemoDeployStep::handleSftpJobFinished(Core::SftpJobId job, + const QString &error) +{ + if (m_stopped) + return; + + QMap<SftpJobId, DeployInfo>::Iterator it = m_uploadsInProgress.find(job); + if (it == m_uploadsInProgress.end()) { + qWarning("%s: Job %u not found in map.", Q_FUNC_INFO, job); + return; + } + + const DeployInfo &deployInfo = it.value(); + if (!error.isEmpty()) { + raiseError(tr("Failed to upload file %1: %2") + .arg(deployInfo.first.localFilePath, error)); + return; + } + + writeOutput(tr("Successfully uploaded file '%1'.") + .arg(deployInfo.first.localFilePath)); + const QString remoteFilePath = deployInfo.first.remoteDir + '/' + + QFileInfo(deployInfo.first.localFilePath).fileName(); + QByteArray linkCommand = remoteSudo().toUtf8() + " ln -sf " + + deployInfo.second.toUtf8() + ' ' + remoteFilePath.toUtf8(); + SshRemoteProcess::Ptr linkProcess + = m_connection->createRemoteProcess(linkCommand); + connect(linkProcess.data(), SIGNAL(closed(int)), this, + SLOT(handleLinkProcessFinished(int))); + m_linksInProgress.insert(linkProcess, deployInfo.first); + linkProcess->start(); + m_uploadsInProgress.erase(it); +} + +void MaemoDeployStep::handleLinkProcessFinished(int exitStatus) +{ + if (m_stopped) + return; + + SshRemoteProcess * const proc = static_cast<SshRemoteProcess *>(sender()); + + // TODO: List instead of map? We can't use it for lookup anyway. + QMap<SshRemoteProcess::Ptr, MaemoDeployable>::Iterator it; + for (it = m_linksInProgress.begin(); it != m_linksInProgress.end(); ++it) { + if (it.key().data() == proc) + break; + } + if (it == m_linksInProgress.end()) { + qWarning("%s: Remote process %p not found in process list.", + Q_FUNC_INFO, proc); + return; + } + + const MaemoDeployable &deployable = it.value(); + if (exitStatus != SshRemoteProcess::ExitedNormally + || proc->exitCode() != 0) { + raiseError(tr("Deployment failed for file '%1': " + "Could not create link '%2' on remote system.") + .arg(deployable.localFilePath, deployable.remoteDir + '/' + + QFileInfo(deployable.localFilePath).fileName())); + return; + } + + setDeployed(m_connection->connectionParameters().host, it.value()); + m_linksInProgress.erase(it); + if (m_linksInProgress.isEmpty() && m_uploadsInProgress.isEmpty()) { + if (m_needsInstall) { + writeOutput(tr("Installing package ...")); + const QByteArray cmd = remoteSudo().toUtf8() + " dpkg -i " + + packageFileName().toUtf8(); + m_installer = m_connection->createRemoteProcess(cmd); + connect(m_installer.data(), SIGNAL(closed(int)), this, + SLOT(handleInstallationFinished(int))); + connect(m_installer.data(), SIGNAL(outputAvailable(QByteArray)), + this, SLOT(handleInstallerOutput(QByteArray))); + connect(m_installer.data(), + SIGNAL(errorOutputAvailable(QByteArray)), this, + SLOT(handleInstallerErrorOutput(QByteArray))); + m_installer->start(); + } else { + emit done(); + } + } +} + +void MaemoDeployStep::handleInstallationFinished(int exitStatus) +{ + if (m_stopped) + return; + + if (exitStatus != SshRemoteProcess::ExitedNormally + || m_installer->exitCode() != 0) { + raiseError(tr("Installing package failed.")); + } else { + writeOutput(tr("Package installation finished.")); + emit done(); + } +} + +void MaemoDeployStep::handleInstallerOutput(const QByteArray &output) +{ + writeOutput(QString::fromUtf8(output)); +} + +void MaemoDeployStep::handleInstallerErrorOutput(const QByteArray &output) +{ + QTextCharFormat format; + format.setForeground(QBrush(QColor("red"))); + writeOutput(output, format); +} + + +MaemoDeployEventHandler::MaemoDeployEventHandler(MaemoDeployStep *deployStep, + QFutureInterface<bool> &future) + : m_deployStep(deployStep), m_future(future), m_eventLoop(new QEventLoop) +{ + connect(m_deployStep, SIGNAL(done()), this, SLOT(handleDeployingDone())); + connect(m_deployStep, SIGNAL(error()), this, SLOT(handleDeployingFailed())); + QTimer cancelChecker; + connect(&cancelChecker, SIGNAL(timeout()), this, SLOT(checkForCanceled())); + cancelChecker.start(500); + future.reportResult(m_eventLoop->exec() == 0); +} + +void MaemoDeployEventHandler::handleDeployingDone() +{ + m_eventLoop->exit(0); +} + +void MaemoDeployEventHandler::handleDeployingFailed() +{ + m_eventLoop->exit(1); +} + +void MaemoDeployEventHandler::checkForCanceled() +{ + if (m_future.isCanceled()) + handleDeployingFailed(); } } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h index 24d4e6c12940156db2ca5de19caccf84177f80d4..e8a470ea1624cfbde4d41351f1140ac8d91df898 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h @@ -1,10 +1,31 @@ #ifndef MAEMODEPLOYSTEP_H #define MAEMODEPLOYSTEP_H +#include "maemodeployable.h" +#include "maemodeviceconfigurations.h" + +#include <coreplugin/ssh/sftpdefs.h> #include <projectexplorer/buildstep.h> +#include <QtCore/QHash> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QPair> +#include <QtCore/QSharedPointer> + +QT_BEGIN_NAMESPACE +class QEventLoop; +QT_END_NAMESPACE + +namespace Core { +class SftpChannel; +class SshConnection; +class SshRemoteProcess; +} + namespace Qt4ProjectManager { namespace Internal { +class MaemoPackageCreationStep; class MaemoDeployStep : public ProjectExplorer::BuildStep { @@ -12,6 +33,27 @@ class MaemoDeployStep : public ProjectExplorer::BuildStep friend class MaemoDeployStepFactory; public: MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc); + virtual ~MaemoDeployStep(); + MaemoDeviceConfig deviceConfig() const; + bool currentlyNeedsDeployment(const QString &host, + const MaemoDeployable &deployable) const; + void setDeployed(const QString &host, const MaemoDeployable &deployable); + +signals: + void done(); + void error(); + +private slots: + void start(); + void handleConnected(); + void handleConnectionFailure(); + void handleSftpChannelInitialized(); + void handleSftpChannelInitializationFailed(const QString &error); + void handleSftpJobFinished(Core::SftpJobId job, const QString &error); + void handleLinkProcessFinished(int exitStatus); + void handleInstallationFinished(int exitStatus); + void handleInstallerOutput(const QByteArray &output); + void handleInstallerErrorOutput(const QByteArray &output); private: MaemoDeployStep(ProjectExplorer::BuildConfiguration *bc, @@ -20,8 +62,52 @@ private: virtual void run(QFutureInterface<bool> &fi); virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); virtual bool immutable() const { return true; } + virtual QVariantMap toMap() const; + virtual bool fromMap(const QVariantMap &map); + + void ctor(); + void stop(); + void raiseError(const QString &error); + void writeOutput(const QString &text, + const QTextCharFormat &format = QTextCharFormat()); + void addDeployTimesToMap(QVariantMap &map) const; + void getDeployTimesFromMap(const QVariantMap &map); + const MaemoPackageCreationStep *packagingStep() const; + bool deploy(const MaemoDeployable &deployable); + QString uploadDir() const; + QString packageFileName() const; + QString packageFilePath() const; static const QLatin1String Id; + + QSharedPointer<Core::SshConnection> m_connection; + QSharedPointer<Core::SftpChannel> m_uploader; + QSharedPointer<Core::SshRemoteProcess> m_installer; + typedef QPair<MaemoDeployable, QString> DeployInfo; + QMap<Core::SftpJobId, DeployInfo> m_uploadsInProgress; + QMap<QSharedPointer<Core::SshRemoteProcess>, MaemoDeployable> m_linksInProgress; + bool m_needsInstall; + bool m_stopped; + typedef QPair<MaemoDeployable, QString> DeployablePerHost; + QHash<DeployablePerHost, QDateTime> m_lastDeployed; +}; + +class MaemoDeployEventHandler : public QObject +{ + Q_OBJECT +public: + MaemoDeployEventHandler(MaemoDeployStep *deployStep, + QFutureInterface<bool> &future); + +private slots: + void handleDeployingDone(); + void handleDeployingFailed(); + void checkForCanceled(); + +private: + const MaemoDeployStep * const m_deployStep; + const QFutureInterface<bool> m_future; + QEventLoop * const m_eventLoop; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.cpp index 70569eef479591a5f8163483bc17643f1f7dad58..41059e52ffd07de41087fc3235c3218eed9d0107 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.cpp @@ -1,12 +1,19 @@ #include "maemodeploystepwidget.h" #include "ui_maemodeploystepwidget.h" +#include "maemodeploystep.h" +#include "maemorunconfiguration.h" + +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/target.h> + namespace Qt4ProjectManager { namespace Internal { -MaemoDeployStepWidget::MaemoDeployStepWidget() : +MaemoDeployStepWidget::MaemoDeployStepWidget(MaemoDeployStep *step) : ProjectExplorer::BuildStepConfigWidget(), - ui(new Ui::MaemoDeployStepWidget) + ui(new Ui::MaemoDeployStepWidget), + m_step(step) { ui->setupUi(this); } @@ -18,11 +25,23 @@ MaemoDeployStepWidget::~MaemoDeployStepWidget() void MaemoDeployStepWidget::init() { + const ProjectExplorer::RunConfiguration * const rc = + m_step->buildConfiguration()->target()->activeRunConfiguration(); + if (rc) { + connect(qobject_cast<const MaemoRunConfiguration *>(rc), + SIGNAL(deviceConfigurationChanged(ProjectExplorer::Target *)), + this, SLOT(handleDeviceUpdate())); + } +} + +void MaemoDeployStepWidget::handleDeviceUpdate() +{ + emit updateSummary(); } QString MaemoDeployStepWidget::summaryText() const { - return tr("<b>Deploy to device</b> "); + return tr("<b>Deploy to device</b>: ") + m_step->deviceConfig().name; } QString MaemoDeployStepWidget::displayName() const diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.h index 85342b630b867179e900aed9aad3cf5d2a4308ad..4ff469b621f31ff0d56aee250e19eef038c09307 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystepwidget.h @@ -11,13 +11,14 @@ QT_END_NAMESPACE namespace Qt4ProjectManager { namespace Internal { +class MaemoDeployStep; class MaemoDeployStepWidget : public ProjectExplorer::BuildStepConfigWidget { Q_OBJECT public: - MaemoDeployStepWidget(); + MaemoDeployStepWidget(MaemoDeployStep *step); ~MaemoDeployStepWidget(); private: @@ -25,7 +26,10 @@ private: virtual QString summaryText() const; virtual QString displayName() const; + Q_SLOT void handleDeviceUpdate(); + Ui::MaemoDeployStepWidget *ui; + MaemoDeployStep * const m_step; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp index d1d7d6645ef9e4b7818bec15aa202d44d64b5a88..18496019f6da155dc8cc5d3b7bf828f7cf60aa11 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.cpp @@ -36,6 +36,7 @@ #include <coreplugin/icore.h> +#include <QtCore/QCoreApplication> #include <QtCore/QSettings> #include <QtCore/QStringBuilder> #include <QtGui/QDesktopServices> @@ -54,6 +55,11 @@ QString homeDirOnDevice(const QString &uname) : QLatin1String("/home/") + uname; } +QString remoteSudo() +{ + return QLatin1String("/usr/lib/mad-developer/devrootsh"); +} + namespace { const QLatin1String SettingsGroup("MaemoDeviceConfigs"); const QLatin1String IdCounterKey("IdCounter"); @@ -132,7 +138,8 @@ MaemoDeviceConfig::MaemoDeviceConfig(const QSettings &settings, } MaemoDeviceConfig::MaemoDeviceConfig() - : internalId(InvalidId) + : name(QCoreApplication::translate("MaemoDeviceConfig", "(Invalid device)")), + internalId(InvalidId) { } diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h index 43ea377006bf612e22879a01a0ebe7bc04feac7c..6f8ad3a7b04778e141afaec4a8bdcdd351ec0b50 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h @@ -49,6 +49,7 @@ namespace Qt4ProjectManager { namespace Internal { QString homeDirOnDevice(const QString &uname); +QString remoteSudo(); class MaemoDeviceConfig { diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp index 69bff242583ad8d82e59c0e98d639014ff6b475b..9a76be87c4b4c325f9d24dbf874a184b76bfe285 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp @@ -29,6 +29,7 @@ #include "maemorunconfiguration.h" +#include "maemodeploystep.h" #include "maemopackagecreationstep.h" #include "maemorunconfigurationwidget.h" #include "maemotoolchain.h" @@ -67,7 +68,6 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent, , m_gdbPath(source->m_gdbPath) , m_devConfig(source->m_devConfig) , m_arguments(source->m_arguments) - , m_lastDeployed(source->m_lastDeployed) { init(); } @@ -123,32 +123,11 @@ QVariantMap MaemoRunConfiguration::toMap() const QVariantMap map(RunConfiguration::toMap()); map.insert(DeviceIdKey, m_devConfig.internalId); map.insert(ArgumentsKey, m_arguments); - addDeployTimesToMap(map); const QDir dir = QDir(target()->project()->projectDirectory()); map.insert(ProFileKey, dir.relativeFilePath(m_proFilePath)); - return map; } -void MaemoRunConfiguration::addDeployTimesToMap(QVariantMap &map) const -{ - QVariantList hostList; - QVariantList fileList; - QVariantList remotePathList; - QVariantList timeList; - typedef QHash<DeployablePerHost, QDateTime>::ConstIterator DepIt; - for (DepIt it = m_lastDeployed.begin(); it != m_lastDeployed.end(); ++it) { - hostList << it.key().first.localFilePath; - remotePathList << it.key().first.remoteDir; - fileList << it.key().second; - timeList << it.value(); - } - map.insert(LastDeployedHostsKey, hostList); - map.insert(LastDeployedFilesKey, fileList); - map.insert(LastDeployedRemotePathsKey, remotePathList); - map.insert(LastDeployedTimesKey, timeList); -} - bool MaemoRunConfiguration::fromMap(const QVariantMap &map) { if (!RunConfiguration::fromMap(map)) @@ -157,47 +136,12 @@ bool MaemoRunConfiguration::fromMap(const QVariantMap &map) setDeviceConfig(MaemoDeviceConfigurations::instance(). find(map.value(DeviceIdKey, 0).toInt())); m_arguments = map.value(ArgumentsKey).toStringList(); - getDeployTimesFromMap(map); const QDir dir = QDir(target()->project()->projectDirectory()); m_proFilePath = dir.filePath(map.value(ProFileKey).toString()); return true; } -void MaemoRunConfiguration::getDeployTimesFromMap(const QVariantMap &map) -{ - const QVariantList &hostList = map.value(LastDeployedHostsKey).toList(); - const QVariantList &fileList = map.value(LastDeployedFilesKey).toList(); - const QVariantList &remotePathList - = map.value(LastDeployedRemotePathsKey).toList(); - const QVariantList &timeList = map.value(LastDeployedTimesKey).toList(); - const int elemCount - = qMin(qMin(hostList.size(), fileList.size()), - qMin(remotePathList.size(), timeList.size())); - for (int i = 0; i < elemCount; ++i) { - const MaemoDeployable d(fileList.at(i).toString(), - remotePathList.at(i).toString()); - m_lastDeployed.insert(DeployablePerHost(d, hostList.at(i).toString()), - timeList.at(i).toDateTime()); - } -} - -bool MaemoRunConfiguration::currentlyNeedsDeployment(const QString &host, - const MaemoDeployable &deployable) const -{ - const QDateTime &lastDeployed - = m_lastDeployed.value(DeployablePerHost(deployable, host)); - return !lastDeployed.isValid() - || QFileInfo(deployable.localFilePath).lastModified() > lastDeployed; -} - -void MaemoRunConfiguration::setDeployed(const QString &host, - const MaemoDeployable &deployable) -{ - m_lastDeployed.insert(DeployablePerHost(deployable, host), - QDateTime::currentDateTime()); -} - void MaemoRunConfiguration::setDeviceConfig(const MaemoDeviceConfig &devConf) { m_devConfig = devConf; @@ -239,6 +183,20 @@ const MaemoPackageCreationStep *MaemoRunConfiguration::packageStep() const return 0; } +MaemoDeployStep *MaemoRunConfiguration::deployStep() const +{ + const QList<ProjectExplorer::BuildStep *> &buildSteps + = activeQt4BuildConfiguration()->steps(ProjectExplorer::BuildStep::Deploy); + for (int i = buildSteps.count() - 1; i >= 0; --i) { + MaemoDeployStep * const step + = qobject_cast<MaemoDeployStep*>(buildSteps.at(i)); + if (step) + return step; + } + Q_ASSERT(!"Impossible: Maemo run configuration without deploy step."); + return 0; +} + QString MaemoRunConfiguration::maddeRoot() const { if (const MaemoToolChain *tc = toolchain()) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h index 04b9f1cc3c3a7604ddb3c73f32124c0f5948f05f..6dd85e9e5711b61e2260a117331fd68525354132 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h @@ -53,6 +53,7 @@ class Qt4BuildConfiguration; class Qt4ProFileNode; class Qt4Target; +class MaemoDeployStep; class MaemoPackageCreationStep; class MaemoRunConfigurationFactory; @@ -70,11 +71,8 @@ public: Qt4Target *qt4Target() const; Qt4BuildConfiguration *activeQt4BuildConfiguration() const; - bool currentlyNeedsDeployment(const QString &host, - const MaemoDeployable &deployable) const; - void setDeployed(const QString &host, const MaemoDeployable &deployable); - const MaemoPackageCreationStep *packageStep() const; + MaemoDeployStep *deployStep() const; QString maddeRoot() const; QString executable() const; @@ -107,17 +105,12 @@ private slots: private: void init(); const MaemoToolChain *toolchain() const; - void addDeployTimesToMap(QVariantMap &map) const; - void getDeployTimesFromMap(const QVariantMap &map); QString m_proFilePath; mutable QString m_gdbPath; MaemoDeviceConfig m_devConfig; QStringList m_arguments; - - typedef QPair<MaemoDeployable, QString> DeployablePerHost; - QHash<DeployablePerHost, QDateTime> m_lastDeployed; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp index 4d5a3cbc57c8f8519813317864de5e3fea5465da..5dee500af98abe3bfb2c70dd6c5c12c552231fd4 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp @@ -35,11 +35,11 @@ #include "maemoruncontrol.h" #include "maemodeployables.h" +#include "maemodeploystep.h" #include "maemopackagecreationstep.h" #include "maemorunconfiguration.h" #include <coreplugin/icore.h> -#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/ssh/sftpchannel.h> #include <coreplugin/ssh/sshconnection.h> #include <coreplugin/ssh/sshremoteprocess.h> @@ -47,15 +47,12 @@ #include <debugger/debuggerplugin.h> #include <debugger/debuggerrunner.h> #include <extensionsystem/pluginmanager.h> +#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/toolchain.h> +#include <qt4projectmanager/qt4buildconfiguration.h> #include <utils/qtcassert.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <QtCore/QCryptographicHash> -#include <QtCore/QDir> #include <QtCore/QFileInfo> -#include <QtCore/QFuture> -#include <QtCore/QProcess> #include <QtCore/QStringBuilder> #include <QtGui/QMessageBox> @@ -137,236 +134,11 @@ void AbstractMaemoRunControl::stop() } else if (m_initialCleaner && m_initialCleaner->isRunning()) { disconnect(m_initialCleaner.data(), 0, this, 0); emit finished(); - } else if (m_installer && m_installer->isRunning()) { - disconnect(m_installer.data(), 0, this, 0); - emit finished(); - } else if (isDeploying()) { - m_uploadsInProgress.clear(); - m_linksInProgress.clear(); - disconnect(m_uploader.data(), 0, this, 0); - m_progress.reportCanceled(); - m_progress.reportFinished(); - emit finished(); } else { stopInternal(); } } -void AbstractMaemoRunControl::startDeployment() -{ - QTC_ASSERT(m_runConfig, return); - - m_uploader = m_connection->createSftpChannel(); - connect(m_uploader.data(), SIGNAL(initialized()), this, - SLOT(handleSftpChannelInitialized())); - connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this, - SLOT(handleSftpChannelInitializationFailed(QString))); - connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)), - this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString))); - m_uploader->initialize(); -} - -void AbstractMaemoRunControl::handleSftpChannelInitialized() -{ - if (m_stopped) - return; - - m_uploadsInProgress.clear(); - m_linksInProgress.clear(); - m_needsInstall = false; - const QList<MaemoDeployable> &deployables = filesToDeploy(); - foreach (const MaemoDeployable &d, deployables) { - const QString fileName = QFileInfo(d.localFilePath).fileName(); - const QString remoteFilePath = d.remoteDir + '/' + fileName; - const QString uploadFilePath = uploadDir() + '/' + fileName + '.' - + QCryptographicHash::hash(remoteFilePath.toUtf8(), - QCryptographicHash::Md5).toHex(); - const SftpJobId job = m_uploader->uploadFile(d.localFilePath, - uploadFilePath, SftpOverwriteExisting); - if (job == SftpInvalidJob) { - handleError(tr("Upload failed: Could not open file '%1'") - .arg(d.localFilePath)); - return; - } - emit appendMessage(this, tr("Started uploading file '%1'.") - .arg(d.localFilePath), false); - m_uploadsInProgress.insert(job, DeployInfo(d, uploadFilePath)); - } - - Core::ICore::instance()->progressManager() - ->addTask(m_progress.future(), tr("Deploying"), - QLatin1String("Maemo.Deploy")); - if (!m_uploadsInProgress.isEmpty()) { - m_progress.setProgressRange(0, m_uploadsInProgress.count()); - m_progress.setProgressValue(0); - m_progress.reportStarted(); - } else { - m_progress.reportFinished(); - startExecutionIfPossible(); - } -} - -void AbstractMaemoRunControl::handleSftpChannelInitializationFailed(const QString &error) -{ - if (m_stopped) - return; - handleError(tr("Could not set up SFTP connection: %1").arg(error)); -} - -void AbstractMaemoRunControl::handleSftpJobFinished(Core::SftpJobId job, - const QString &error) -{ - if (m_stopped) - return; - - QMap<SftpJobId, DeployInfo>::Iterator it = m_uploadsInProgress.find(job); - if (it == m_uploadsInProgress.end()) { - qWarning("%s: Job %u not found in map.", Q_FUNC_INFO, job); - return; - } - - const DeployInfo &deployInfo = it.value(); - if (!error.isEmpty()) { - handleError(tr("Failed to upload file %1: %2") - .arg(deployInfo.first.localFilePath, error)); - return; - } - - m_progress.setProgressValue(m_progress.progressValue() + 1); - appendMessage(this, tr("Successfully uploaded file '%1'.") - .arg(deployInfo.first.localFilePath), false); - - const QString remoteFilePath = deployInfo.first.remoteDir + '/' - + QFileInfo(deployInfo.first.localFilePath).fileName(); - QByteArray linkCommand = remoteSudo().toUtf8() + " ln -sf " - + deployInfo.second.toUtf8() + ' ' + remoteFilePath.toUtf8(); - SshRemoteProcess::Ptr linkProcess - = m_connection->createRemoteProcess(linkCommand); - connect(linkProcess.data(), SIGNAL(closed(int)), this, - SLOT(handleLinkProcessFinished(int))); - m_linksInProgress.insert(linkProcess, deployInfo.first); - linkProcess->start(); - m_uploadsInProgress.erase(it); -} - -void AbstractMaemoRunControl::handleLinkProcessFinished(int exitStatus) -{ - if (m_stopped) - return; - - SshRemoteProcess * const proc = static_cast<SshRemoteProcess *>(sender()); - - // TODO: List instead of map? We can't use it for lookup anyway. - QMap<SshRemoteProcess::Ptr, MaemoDeployable>::Iterator it; - for (it = m_linksInProgress.begin(); it != m_linksInProgress.end(); ++it) { - if (it.key().data() == proc) - break; - } - if (it == m_linksInProgress.end()) { - qWarning("%s: Remote process %p not found in process list.", - Q_FUNC_INFO, proc); - return; - } - - const MaemoDeployable &deployable = it.value(); - if (exitStatus != SshRemoteProcess::ExitedNormally - || proc->exitCode() != 0) { - handleError(tr("Deployment failed for file '%1': " - "Could not create link '%2' on remote system.") - .arg(deployable.localFilePath, deployable.remoteDir + '/' - + QFileInfo(deployable.localFilePath).fileName())); - return; - } - - m_runConfig->setDeployed(m_devConfig.server.host, it.value()); - m_linksInProgress.erase(it); - if (m_linksInProgress.isEmpty() && m_uploadsInProgress.isEmpty()) { - if (m_needsInstall) { - emit appendMessage(this, tr("Installing package ..."), false); - const QByteArray cmd = remoteSudo().toUtf8() + " dpkg -i " - + packageFileName().toUtf8(); - m_installer = m_connection->createRemoteProcess(cmd); - connect(m_installer.data(), SIGNAL(closed(int)), this, - SLOT(handleInstallationFinished(int))); - connect(m_installer.data(), SIGNAL(outputAvailable(QByteArray)), - this, SLOT(handleRemoteOutput(QByteArray))); - connect(m_installer.data(), - SIGNAL(errorOutputAvailable(QByteArray)), this, - SLOT(handleRemoteErrorOutput(QByteArray))); - m_installer->start(); - } else { - handleDeploymentFinished(); - } - } -} - -void AbstractMaemoRunControl::handleInstallationFinished(int exitStatus) -{ - if (m_stopped) - return; - - if (exitStatus != SshRemoteProcess::ExitedNormally - || m_installer->exitCode() != 0) { - handleError(tr("Installing package failed.")); - } else { - emit appendMessage(this, tr("Package installation finished."), false); - handleDeploymentFinished(); - } -} - -void AbstractMaemoRunControl::handleDeploymentFinished() -{ - emit appendMessage(this, tr("Deployment finished."), false); - m_progress.reportFinished(); - startExecutionIfPossible(); -} - -QList<MaemoDeployable> AbstractMaemoRunControl::filesToDeploy() -{ - QList<MaemoDeployable> deployableList; - if (m_runConfig->packageStep()->isPackagingEnabled()) { - const MaemoDeployable d(packageFilePath(), uploadDir()); - m_needsInstall = addDeployableIfNeeded(deployableList, d); - } else { - const MaemoDeployables * const deployables - = m_runConfig->packageStep()->deployables(); - const int deployableCount = deployables->deployableCount(); - for (int i = 0; i < deployableCount; ++i) { - const MaemoDeployable &d = deployables->deployableAt(i); - addDeployableIfNeeded(deployableList, d); - } - m_needsInstall = false; - } - return deployableList; -} - -bool AbstractMaemoRunControl::addDeployableIfNeeded(QList<MaemoDeployable> &deployables, - const MaemoDeployable &deployable) -{ - if (m_runConfig->currentlyNeedsDeployment(m_devConfig.server.host, - deployable)) { - deployables << deployable; - return true; - } else { - return false; - } -} - -bool AbstractMaemoRunControl::isDeploying() const -{ - return !m_uploadsInProgress.isEmpty() || !m_linksInProgress.isEmpty(); -} - -QString AbstractMaemoRunControl::packageFileName() const -{ - return QFileInfo(packageFilePath()).fileName(); -} - -QString AbstractMaemoRunControl::packageFilePath() const -{ - return m_runConfig->packageStep()->packageFilePath(); -} - QString AbstractMaemoRunControl::executableFilePathOnTarget() const { const MaemoDeployables * const deployables @@ -374,11 +146,6 @@ QString AbstractMaemoRunControl::executableFilePathOnTarget() const return deployables->remoteExecutableFilePath(m_runConfig->executable()); } -bool AbstractMaemoRunControl::isCleaning() const -{ - return m_initialCleaner && m_initialCleaner->isRunning(); -} - void AbstractMaemoRunControl::startExecutionIfPossible() { if (executableFilePathOnTarget().isEmpty()) { @@ -436,7 +203,7 @@ void AbstractMaemoRunControl::handleRemoteErrorOutput(const QByteArray &output) bool AbstractMaemoRunControl::isRunning() const { - return isDeploying() || (m_runner && m_runner->isRunning()); + return m_runner && m_runner->isRunning(); } void AbstractMaemoRunControl::stopRunning(bool forDebugging) @@ -488,7 +255,7 @@ void AbstractMaemoRunControl::handleInitialCleanupFinished(int exitStatus) .arg(m_initialCleaner->errorString())); } else { emit appendMessage(this, tr("Initial cleanup done."), false); - startDeployment(); + startExecutionIfPossible(); } } @@ -507,11 +274,6 @@ const QString AbstractMaemoRunControl::uploadDir() const return homeDirOnDevice(m_devConfig.server.uname); } -QString AbstractMaemoRunControl::remoteSudo() const -{ - return QLatin1String("/usr/lib/mad-developer/devrootsh"); -} - const QString AbstractMaemoRunControl::targetCmdLinePrefix() const { return QString::fromLocal8Bit("%1 chmod a+x %2 && source /etc/profile && DISPLAY=:0.0 ") @@ -565,6 +327,7 @@ MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration) : AbstractMaemoRunControl(runConfiguration, ProjectExplorer::Constants::DEBUGMODE) , m_debuggerRunControl(0) , m_startParams(new DebuggerStartParameters) + , m_uploadJob(SftpInvalidJob) { #ifdef USE_GDBSERVER m_startParams->startMode = AttachToRemote; @@ -607,27 +370,102 @@ QString MaemoDebugRunControl::remoteCall() const } void MaemoDebugRunControl::startExecution() +{ + const QString &dumperLib = m_runConfig->dumperLib(); + if (!dumperLib.isEmpty() + && m_runConfig->deployStep()->currentlyNeedsDeployment(m_devConfig.server.host, + MaemoDeployable(dumperLib, uploadDir()))) { + m_uploader = m_connection->createSftpChannel(); + connect(m_uploader.data(), SIGNAL(initialized()), this, + SLOT(handleSftpChannelInitialized())); + connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this, + SLOT(handleSftpChannelInitializationFailed(QString))); + connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)), + this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString))); + m_uploader->initialize(); + } else { + startDebugging(); + } +} + +void MaemoDebugRunControl::handleSftpChannelInitialized() +{ + if (m_stopped) + return; + + const QString dumperLib = m_runConfig->dumperLib(); + const QString fileName = QFileInfo(dumperLib).fileName(); + const QString remoteFilePath = uploadDir() + '/' + fileName; + m_uploadJob = m_uploader->uploadFile(dumperLib, remoteFilePath, + SftpOverwriteExisting); + if (m_uploadJob == SftpInvalidJob) { + handleError(tr("Upload failed: Could not open file '%1'") + .arg(dumperLib)); + } else { + emit appendMessage(this, + tr("Started uploading debugging helpers ('%1').").arg(dumperLib), + false); + } +} + +void MaemoDebugRunControl::handleSftpChannelInitializationFailed(const QString &error) +{ + handleError(error); +} + +void MaemoDebugRunControl::handleSftpJobFinished(Core::SftpJobId job, + const QString &error) +{ + if (m_stopped) + return; + + if (job != m_uploadJob) { + qWarning("Warning: Unknown debugging helpers upload job %d finished.", job); + return; + } + + if (!error.isEmpty()) { + handleError(tr("Error: Could not upload debugging helpers.")); + } else { + m_runConfig->deployStep()->setDeployed(m_devConfig.server.host, + MaemoDeployable(m_runConfig->dumperLib(), uploadDir())); + emit appendMessage(this, + tr("Finished uploading debugging helpers."), false); + startDebugging(); + } +} + +void MaemoDebugRunControl::startDebugging() { #ifdef USE_GDBSERVER AbstractMaemoRunControl::startExecution(); #else - startDebugging(); + DebuggerPlugin::startDebugger(m_debuggerRunControl); #endif } -void MaemoDebugRunControl::startDebugging() +bool MaemoDebugRunControl::isDeploying() const { - DebuggerPlugin::startDebugger(m_debuggerRunControl); + return m_uploader && m_uploadJob != SftpInvalidJob; } void MaemoDebugRunControl::stopInternal() { - m_debuggerRunControl->engine()->quitDebugger(); + if (isDeploying()) { + disconnect(m_uploader.data(), 0, this, 0); + m_uploader->closeChannel(); + m_uploadJob = SftpInvalidJob; + emit finished(); + } else if (m_debuggerRunControl && m_debuggerRunControl->engine()) { + m_debuggerRunControl->engine()->quitDebugger(); + } else { + emit finished(); + } } bool MaemoDebugRunControl::isRunning() const { - return AbstractMaemoRunControl::isRunning() + return isDeploying() || AbstractMaemoRunControl::isRunning() || m_debuggerRunControl->state() != DebuggerNotReady; } @@ -642,7 +480,7 @@ void MaemoDebugRunControl::debuggingFinished() void MaemoDebugRunControl::handleRemoteProcessStarted() { - startDebugging(); + DebuggerPlugin::startDebugger(m_debuggerRunControl); } void MaemoDebugRunControl::debuggerOutput(const QString &output) @@ -659,14 +497,5 @@ QString MaemoDebugRunControl::gdbServerPort() const // but we will make sure we use the right port from the information file. } -QList<MaemoDeployable> MaemoDebugRunControl::filesToDeploy() -{ - QList<MaemoDeployable> deployables - = AbstractMaemoRunControl::filesToDeploy(); - const MaemoDeployable d(m_runConfig->dumperLib(), uploadDir()); - addDeployableIfNeeded(deployables, d); - return deployables; -} - } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h index a5ede3fde264cadfa2569c3bfd1e5dc4f5de9e1a..a9af1e60719e858cd74b7d7b5d1f2e746960a0fb 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h @@ -36,14 +36,10 @@ #define MAEMORUNCONTROL_H #include "maemodeviceconfigurations.h" -#include "maemodeployable.h" #include <coreplugin/ssh/sftpdefs.h> #include <projectexplorer/runconfiguration.h> -#include <QtCore/QFutureInterface> -#include <QtCore/QMap> -#include <QtCore/QScopedPointer> #include <QtCore/QString> QT_BEGIN_NAMESPACE @@ -78,7 +74,6 @@ protected: virtual void start(); virtual void stop(); - void startDeployment(); void stopRunning(bool forDebugging); virtual void startExecution(); void handleError(const QString &errString); @@ -87,22 +82,12 @@ protected: const QString targetCmdLinePrefix() const; QString targetCmdLineSuffix() const; const QString uploadDir() const; - QString packageFileName() const; - QString packageFilePath() const; QString executableFilePathOnTarget() const; - virtual QList<MaemoDeployable> filesToDeploy(); - bool addDeployableIfNeeded(QList<MaemoDeployable> &deployables, - const MaemoDeployable &deployable); private slots: void handleConnected(); void handleConnectionFailure(); void handleInitialCleanupFinished(int exitStatus); - void handleSftpChannelInitialized(); - void handleSftpChannelInitializationFailed(const QString &error); - void handleSftpJobFinished(Core::SftpJobId job, const QString &error); - void handleLinkProcessFinished(int exitStatus); - void handleInstallationFinished(int exitStatus); virtual void handleRemoteProcessStarted() {} void handleRemoteProcessFinished(int exitStatus); void handleRemoteOutput(const QByteArray &output); @@ -111,6 +96,8 @@ private slots: protected: MaemoRunConfiguration *m_runConfig; // TODO this pointer can be invalid const MaemoDeviceConfig m_devConfig; + QSharedPointer<Core::SshConnection> m_connection; + bool m_stopped; private: virtual void stopInternal()=0; @@ -120,25 +107,10 @@ private: void cancelActions(); template<class SshChannel> void closeSshChannel(SshChannel &channel); void startExecutionIfPossible(); - bool isCleaning() const; - bool isDeploying() const; - QString remoteSudo() const; - QString uploadFilePath(const MaemoDeployable &deployable) const; - void handleDeploymentFinished(); - QFutureInterface<void> m_progress; - QSharedPointer<Core::SshConnection> m_connection; - QSharedPointer<Core::SftpChannel> m_uploader; - QSharedPointer<Core::SshRemoteProcess> m_installer; QSharedPointer<Core::SshRemoteProcess> m_runner; QSharedPointer<Core::SshRemoteProcess> m_stopper; QSharedPointer<Core::SshRemoteProcess> m_initialCleaner; - - typedef QPair<MaemoDeployable, QString> DeployInfo; - QMap<Core::SftpJobId, DeployInfo> m_uploadsInProgress; - QMap<QSharedPointer<Core::SshRemoteProcess>, MaemoDeployable> m_linksInProgress; - bool m_needsInstall; - bool m_stopped; }; class MaemoRunControl : public AbstractMaemoRunControl @@ -165,18 +137,23 @@ private slots: virtual void handleRemoteProcessStarted(); void debuggerOutput(const QString &output); void debuggingFinished(); + void handleSftpChannelInitialized(); + void handleSftpChannelInitializationFailed(const QString &error); + void handleSftpJobFinished(Core::SftpJobId job, const QString &error); private: virtual void stopInternal(); virtual void startExecution(); virtual QString remoteCall() const; - virtual QList<MaemoDeployable> filesToDeploy(); QString gdbServerPort() const; void startDebugging(); + bool isDeploying() const; Debugger::DebuggerRunControl *m_debuggerRunControl; QSharedPointer<Debugger::DebuggerStartParameters> m_startParams; + QSharedPointer<Core::SftpChannel> m_uploader; + Core::SftpJobId m_uploadJob; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt4target.cpp b/src/plugins/qt4projectmanager/qt4target.cpp index e63228fbc87247643fd5b59b4bcea0aca1e7c3d9..4f262dbea038c220bbd176b07250537a665d9184 100644 --- a/src/plugins/qt4projectmanager/qt4target.cpp +++ b/src/plugins/qt4projectmanager/qt4target.cpp @@ -288,8 +288,8 @@ Qt4BuildConfiguration *Qt4Target::addQt4BuildConfiguration(QString displayName, } else if (id() == Constants::MAEMO_DEVICE_TARGET_ID) { bc->insertStep(ProjectExplorer::BuildStep::Deploy, 2, new MaemoPackageCreationStep(bc)); -// bc->insertStep(ProjectExplorer::BuildStep::Deploy, 2, -// new MaemoDeployStep(bc)); + bc->insertStep(ProjectExplorer::BuildStep::Deploy, 3, + new MaemoDeployStep(bc)); } MakeStep* cleanStep = new MakeStep(bc);