2010-07-15 13:58:18 +02:00
|
|
|
/**************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2011-01-11 16:28:15 +01:00
|
|
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
2010-07-15 13:58:18 +02:00
|
|
|
**
|
|
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** No Commercial Usage
|
2010-07-15 13:58:18 +02:00
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** 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.
|
2010-07-15 13:58:18 +02:00
|
|
|
**
|
|
|
|
|
** 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.
|
|
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** 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.
|
2010-07-15 13:58:18 +02:00
|
|
|
**
|
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
2010-07-22 13:08:25 +02:00
|
|
|
#include "s60deploystep.h"
|
2010-07-15 13:58:18 +02:00
|
|
|
|
|
|
|
|
#include "qt4buildconfiguration.h"
|
2010-08-10 12:31:55 +02:00
|
|
|
#include "s60deployconfiguration.h"
|
2010-07-15 13:58:18 +02:00
|
|
|
#include "s60devicerunconfiguration.h"
|
|
|
|
|
#include "s60runconfigbluetoothstarter.h"
|
2011-02-07 14:26:34 +01:00
|
|
|
#include "codadevice.h"
|
2011-01-18 16:45:42 +01:00
|
|
|
#include "trkruncontrol.h"
|
2010-07-15 13:58:18 +02:00
|
|
|
|
|
|
|
|
#include <coreplugin/icore.h>
|
2010-07-16 14:00:41 +02:00
|
|
|
#include <projectexplorer/buildsteplist.h>
|
2010-07-15 13:58:18 +02:00
|
|
|
#include <projectexplorer/target.h>
|
2010-07-16 14:00:41 +02:00
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
2010-07-15 13:58:18 +02:00
|
|
|
#include <qt4projectmanagerconstants.h>
|
|
|
|
|
|
2010-11-03 10:03:48 +01:00
|
|
|
#include <symbianutils/launcher.h>
|
|
|
|
|
#include <symbianutils/symbiandevicemanager.h>
|
2011-01-07 15:47:22 +01:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2010-11-03 10:03:48 +01:00
|
|
|
#include <QtGui/QMessageBox>
|
|
|
|
|
#include <QtGui/QMainWindow>
|
|
|
|
|
|
|
|
|
|
#include <QtCore/QTimer>
|
|
|
|
|
#include <QtCore/QDateTime>
|
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
|
#include <QtCore/QEventLoop>
|
2011-01-07 15:47:22 +01:00
|
|
|
#include <QtCore/QFile>
|
|
|
|
|
#include <QtCore/QFileInfo>
|
|
|
|
|
|
|
|
|
|
#include <QtNetwork/QTcpSocket>
|
2010-11-03 10:03:48 +01:00
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
using namespace Qt4ProjectManager::Internal;
|
|
|
|
|
|
2011-01-25 09:18:45 +01:00
|
|
|
enum {debug = 0};
|
2011-01-07 15:47:22 +01:00
|
|
|
|
2011-01-31 15:52:49 +01:00
|
|
|
static const quint64 DEFAULT_CHUNK_SIZE = 40000;
|
2011-01-07 15:47:22 +01:00
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
namespace {
|
2011-01-07 15:47:22 +01:00
|
|
|
const char * const S60_DEPLOY_STEP_ID = "Qt4ProjectManager.S60DeployStep";
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool ensureDeleteFile(const QString &fileName, QString *errorMessage)
|
|
|
|
|
{
|
|
|
|
|
QFile file(fileName);
|
|
|
|
|
if (file.exists() && !file.remove()) {
|
|
|
|
|
*errorMessage = S60DeployStep::tr("Unable to remove existing file '%1': %2").arg(fileName, file.errorString());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool renameFile(const QString &sourceName, const QString &targetName,
|
|
|
|
|
QString *errorMessage)
|
|
|
|
|
{
|
|
|
|
|
if (sourceName == targetName)
|
|
|
|
|
return true;
|
|
|
|
|
if (!ensureDeleteFile(targetName, errorMessage))
|
|
|
|
|
return false;
|
|
|
|
|
QFile source(sourceName);
|
|
|
|
|
if (!source.rename(targetName)) {
|
|
|
|
|
*errorMessage = S60DeployStep::tr("Unable to rename file '%1' to '%2': %3")
|
2011-01-07 15:47:22 +01:00
|
|
|
.arg(sourceName, targetName, source.errorString());
|
2010-07-15 13:58:18 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #pragma mark -- S60DeployStep
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc,
|
2010-07-15 13:58:18 +02:00
|
|
|
S60DeployStep *bs):
|
2011-01-07 15:47:22 +01:00
|
|
|
BuildStep(bc, bs), m_timer(0),
|
|
|
|
|
m_releaseDeviceAfterLauncherFinish(bs->m_releaseDeviceAfterLauncherFinish),
|
|
|
|
|
m_handleDeviceRemoval(bs->m_handleDeviceRemoval),
|
|
|
|
|
m_launcher(0),
|
|
|
|
|
m_eventLoop(0),
|
|
|
|
|
m_state(StateUninit),
|
|
|
|
|
m_putWriteOk(false),
|
|
|
|
|
m_putLastChunkSize(0),
|
2011-01-14 14:34:13 +01:00
|
|
|
m_putChunkSize(DEFAULT_CHUNK_SIZE),
|
2011-01-07 15:47:22 +01:00
|
|
|
m_currentFileIndex(0),
|
|
|
|
|
m_channel(bs->m_channel),
|
2011-01-31 16:22:37 +01:00
|
|
|
m_deployCanceled(false),
|
|
|
|
|
m_copyProgress(0)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-08-19 12:26:21 +02:00
|
|
|
ctor();
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
S60DeployStep::S60DeployStep(ProjectExplorer::BuildStepList *bc):
|
2011-01-07 15:47:22 +01:00
|
|
|
BuildStep(bc, QLatin1String(S60_DEPLOY_STEP_ID)), m_timer(0),
|
|
|
|
|
m_releaseDeviceAfterLauncherFinish(true),
|
|
|
|
|
m_handleDeviceRemoval(true),
|
|
|
|
|
m_launcher(0),
|
|
|
|
|
m_eventLoop(0),
|
|
|
|
|
m_state(StateUninit),
|
|
|
|
|
m_putWriteOk(false),
|
|
|
|
|
m_putLastChunkSize(0),
|
2011-01-14 14:34:13 +01:00
|
|
|
m_putChunkSize(DEFAULT_CHUNK_SIZE),
|
2011-01-07 15:47:22 +01:00
|
|
|
m_currentFileIndex(0),
|
2011-01-18 16:45:42 +01:00
|
|
|
m_channel(S60DeployConfiguration::CommunicationTrkSerialConnection),
|
2011-01-31 16:22:37 +01:00
|
|
|
m_deployCanceled(false),
|
|
|
|
|
m_copyProgress(0)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-08-19 12:26:21 +02:00
|
|
|
ctor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::ctor()
|
|
|
|
|
{
|
|
|
|
|
//: Qt4 Deploystep display name
|
|
|
|
|
setDefaultDisplayName(tr("Deploy"));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
S60DeployStep::~S60DeployStep()
|
|
|
|
|
{
|
|
|
|
|
delete m_timer;
|
|
|
|
|
delete m_launcher;
|
|
|
|
|
delete m_eventLoop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool S60DeployStep::init()
|
|
|
|
|
{
|
|
|
|
|
Qt4BuildConfiguration *bc = static_cast<Qt4BuildConfiguration *>(buildConfiguration());
|
2011-01-07 15:47:22 +01:00
|
|
|
S60DeployConfiguration *deployConfiguration = static_cast<S60DeployConfiguration *>(bc->target()->activeDeployConfiguration());
|
|
|
|
|
if (!deployConfiguration)
|
2010-07-15 13:58:18 +02:00
|
|
|
return false;
|
2010-08-10 12:31:55 +02:00
|
|
|
m_serialPortName = deployConfiguration->serialPortName();
|
2010-07-15 13:58:18 +02:00
|
|
|
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
|
2010-08-10 12:31:55 +02:00
|
|
|
m_packageFileNamesWithTarget = deployConfiguration->packageFileNamesWithTargetInfo();
|
|
|
|
|
m_signedPackages = deployConfiguration->signedPackages();
|
|
|
|
|
m_installationDrive = deployConfiguration->installationDrive();
|
|
|
|
|
m_silentInstall = deployConfiguration->silentInstall();
|
2010-07-15 13:58:18 +02:00
|
|
|
|
2011-01-07 15:47:22 +01:00
|
|
|
switch (deployConfiguration->communicationChannel()) {
|
2011-01-18 16:45:42 +01:00
|
|
|
case S60DeployConfiguration::CommunicationTrkSerialConnection:
|
2011-01-07 15:47:22 +01:00
|
|
|
break;
|
2011-01-18 16:45:42 +01:00
|
|
|
case S60DeployConfiguration::CommunicationCodaTcpConnection:
|
2011-01-07 15:47:22 +01:00
|
|
|
m_address = deployConfiguration->deviceAddress();
|
|
|
|
|
m_port = deployConfiguration->devicePort().toInt();
|
2011-01-21 13:27:49 +01:00
|
|
|
default:
|
|
|
|
|
break;
|
2010-08-05 15:19:15 +02:00
|
|
|
}
|
2011-01-07 15:47:22 +01:00
|
|
|
m_channel = deployConfiguration->communicationChannel();
|
2010-08-05 15:19:15 +02:00
|
|
|
|
2011-01-24 14:51:46 +01:00
|
|
|
if (m_signedPackages.isEmpty()) {
|
|
|
|
|
appendMessage(tr("No package has been found. Please specify at least one installation package."), true);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
|
2011-01-07 15:47:22 +01:00
|
|
|
QString message;
|
|
|
|
|
if (m_launcher) {
|
2010-07-23 13:40:59 +02:00
|
|
|
trk::Launcher::releaseToDeviceManager(m_launcher);
|
2011-01-07 15:47:22 +01:00
|
|
|
delete m_launcher;
|
|
|
|
|
m_launcher = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, this, &message);
|
|
|
|
|
if (!message.isEmpty() || !m_launcher) {
|
|
|
|
|
if (m_launcher)
|
|
|
|
|
trk::Launcher::releaseToDeviceManager(m_launcher);
|
|
|
|
|
delete m_launcher;
|
|
|
|
|
m_launcher = 0;
|
|
|
|
|
appendMessage(message, true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-01-31 16:22:37 +01:00
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
|
m_launcher->setVerbose(1);
|
|
|
|
|
|
2011-01-07 15:47:22 +01:00
|
|
|
// Prompt the user to start up the Bluetooth connection
|
|
|
|
|
const trk::PromptStartCommunicationResult src =
|
|
|
|
|
S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
|
|
|
|
|
0, &message);
|
|
|
|
|
if (src != trk::PromptStartCommunicationConnected) {
|
|
|
|
|
if (!message.isEmpty())
|
|
|
|
|
trk::Launcher::releaseToDeviceManager(m_launcher);
|
|
|
|
|
delete m_launcher;
|
|
|
|
|
m_launcher = 0;
|
|
|
|
|
appendMessage(message, true);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2010-07-23 13:40:59 +02:00
|
|
|
}
|
2010-07-15 13:58:18 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariantMap S60DeployStep::toMap() const
|
|
|
|
|
{
|
|
|
|
|
return BuildStep::toMap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool S60DeployStep::fromMap(const QVariantMap &map)
|
|
|
|
|
{
|
|
|
|
|
return BuildStep::fromMap(map);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::appendMessage(const QString &error, bool isError)
|
|
|
|
|
{
|
|
|
|
|
emit addOutput(error, isError?ProjectExplorer::BuildStep::ErrorMessageOutput:
|
|
|
|
|
ProjectExplorer::BuildStep::MessageOutput);
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-07 15:47:22 +01:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
bool S60DeployStep::processPackageName(QString &errorMessage)
|
|
|
|
|
{
|
2010-07-23 16:37:10 +02:00
|
|
|
for (int i = 0; i < m_signedPackages.count(); ++i) {
|
|
|
|
|
QFileInfo packageInfo(m_signedPackages.at(i));
|
2010-07-15 13:58:18 +02:00
|
|
|
// support for 4.6.1 and pre, where make sis creates 'targetname_armX_udeb.sis' instead of 'targetname.sis'
|
2010-07-23 16:37:10 +02:00
|
|
|
QFileInfo packageWithTargetInfo(m_packageFileNamesWithTarget.at(i));
|
2010-07-15 13:58:18 +02:00
|
|
|
// does the 4.6.1 version exist?
|
|
|
|
|
if (packageWithTargetInfo.exists() && packageWithTargetInfo.isFile()) {
|
|
|
|
|
// is the 4.6.1 version newer? (to guard against behavior change Qt Creator 1.3 --> 2.0)
|
|
|
|
|
if (!packageInfo.exists() || packageInfo.lastModified() < packageWithTargetInfo.lastModified()) { //TODO change the QtCore
|
|
|
|
|
// the 'targetname_armX_udeb.sis' crap exists and is new, rename it
|
|
|
|
|
appendMessage(tr("Renaming new package '%1' to '%2'")
|
2010-07-23 16:37:10 +02:00
|
|
|
.arg(QDir::toNativeSeparators(m_packageFileNamesWithTarget.at(i)),
|
|
|
|
|
QDir::toNativeSeparators(m_signedPackages.at(i))), false);
|
|
|
|
|
return renameFile(m_packageFileNamesWithTarget.at(i), m_signedPackages.at(i), &errorMessage);
|
2010-07-15 13:58:18 +02:00
|
|
|
} else {
|
|
|
|
|
// the 'targetname_armX_udeb.sis' crap exists but is old, remove it
|
|
|
|
|
appendMessage(tr("Removing old package '%1'")
|
2010-07-23 16:37:10 +02:00
|
|
|
.arg(QDir::toNativeSeparators(m_packageFileNamesWithTarget.at(i))),
|
2010-07-15 13:58:18 +02:00
|
|
|
false);
|
2010-07-23 16:37:10 +02:00
|
|
|
ensureDeleteFile(m_packageFileNamesWithTarget.at(i), &errorMessage);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
}
|
2010-07-23 16:37:10 +02:00
|
|
|
if (!packageInfo.exists() || !packageInfo.isFile()) {
|
|
|
|
|
errorMessage = tr("'%1': Package file not found").arg(m_signedPackages.at(i));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::start()
|
|
|
|
|
{
|
2010-12-01 13:30:30 +01:00
|
|
|
QString errorMessage;
|
|
|
|
|
|
2011-01-25 09:18:45 +01:00
|
|
|
bool serialConnection = (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection
|
|
|
|
|
|| m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection);
|
|
|
|
|
bool trkClient = m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection;
|
|
|
|
|
|
2011-02-03 17:41:28 +01:00
|
|
|
if ((serialConnection && m_serialPortName.isEmpty())
|
2011-01-25 09:18:45 +01:00
|
|
|
|| (trkClient && !m_launcher)) {
|
|
|
|
|
errorMessage = tr("No device is connected. Please connect a device and try again.");
|
|
|
|
|
reportError(errorMessage);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!trkClient) {
|
2011-02-04 12:08:19 +01:00
|
|
|
QTC_ASSERT(!m_codaDevice.data(), return);
|
2011-01-25 09:18:45 +01:00
|
|
|
if (m_address.isEmpty() && !serialConnection) {
|
2011-01-07 15:47:22 +01:00
|
|
|
errorMessage = tr("No address for a device has been defined. Please define an address and try again.");
|
|
|
|
|
reportError(errorMessage);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure we have the right name of the sis package
|
|
|
|
|
if (processPackageName(errorMessage)) {
|
|
|
|
|
startDeployment();
|
|
|
|
|
} else {
|
2010-07-23 16:37:10 +02:00
|
|
|
errorMessage = tr("Failed to find package %1").arg(errorMessage);
|
2011-01-07 15:47:22 +01:00
|
|
|
reportError(errorMessage);
|
2010-07-15 13:58:18 +02:00
|
|
|
stop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::stop()
|
|
|
|
|
{
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
|
2011-01-07 15:47:22 +01:00
|
|
|
if (m_launcher)
|
|
|
|
|
m_launcher->terminate();
|
|
|
|
|
} else {
|
2011-02-07 14:14:57 +01:00
|
|
|
if (m_codaDevice) {
|
|
|
|
|
disconnect(m_codaDevice.data(), 0, this, 0);
|
|
|
|
|
SymbianUtils::SymbianDeviceManager::instance()->releaseTcfPort(m_codaDevice);
|
2011-01-07 15:47:22 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
emit finished(false);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::setupConnections()
|
|
|
|
|
{
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
|
2011-01-07 15:47:22 +01:00
|
|
|
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)),
|
|
|
|
|
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
|
|
|
|
|
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
|
|
|
|
|
|
|
|
|
|
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(connectFailed(QString)));
|
|
|
|
|
connect(m_launcher, SIGNAL(copyingStarted(QString)), this, SLOT(printCopyingNotice(QString)));
|
|
|
|
|
connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(createFileFailed(QString,QString)));
|
|
|
|
|
connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(writeFileFailed(QString,QString)));
|
|
|
|
|
connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(closeFileFailed(QString,QString)));
|
|
|
|
|
connect(m_launcher, SIGNAL(installingStarted(QString)), this, SLOT(printInstallingNotice(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(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
|
2011-01-31 16:22:37 +01:00
|
|
|
connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(setCopyProgress(int)));
|
2011-01-07 15:47:22 +01:00
|
|
|
} else {
|
2011-02-04 12:08:19 +01:00
|
|
|
connect(m_codaDevice.data(), SIGNAL(error(QString)), this, SLOT(slotError(QString)));
|
|
|
|
|
connect(m_codaDevice.data(), SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(QString)));
|
2011-02-07 14:14:57 +01:00
|
|
|
connect(m_codaDevice.data(), SIGNAL(tcfEvent(Coda::CodaEvent)), this, SLOT(slotCodaEvent(Coda::CodaEvent)), Qt::DirectConnection);
|
2011-02-04 12:08:19 +01:00
|
|
|
connect(m_codaDevice.data(), SIGNAL(serialPong(QString)), this, SLOT(slotSerialPong(QString)));
|
2011-01-07 15:47:22 +01:00
|
|
|
connect(this, SIGNAL(manualInstallation()), this, SLOT(showManualInstallationInfo()));
|
|
|
|
|
}
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::startDeployment()
|
|
|
|
|
{
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
|
2011-01-07 15:47:22 +01:00
|
|
|
QTC_ASSERT(m_launcher, return);
|
|
|
|
|
}
|
2011-02-07 14:14:57 +01:00
|
|
|
QTC_ASSERT(!m_codaDevice.data(), return);
|
2010-07-15 13:58:18 +02:00
|
|
|
|
2011-02-04 12:08:19 +01:00
|
|
|
// We need to defer setupConnections() in the case of CommunicationCodaSerialConnection
|
|
|
|
|
//setupConnections();
|
2010-07-20 13:37:15 +02:00
|
|
|
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
|
2011-02-04 12:08:19 +01:00
|
|
|
setupConnections();
|
2011-01-07 15:47:22 +01:00
|
|
|
QStringList copyDst;
|
|
|
|
|
foreach (const QString &signedPackage, m_signedPackages)
|
|
|
|
|
copyDst << QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(QFileInfo(signedPackage).fileName());
|
|
|
|
|
|
|
|
|
|
m_launcher->setCopyFileNames(m_signedPackages, copyDst);
|
|
|
|
|
m_launcher->setInstallFileNames(copyDst);
|
|
|
|
|
m_launcher->setInstallationDrive(m_installationDrive);
|
|
|
|
|
m_launcher->setInstallationMode(m_silentInstall?trk::Launcher::InstallationModeSilentAndUser:
|
|
|
|
|
trk::Launcher::InstallationModeUser);
|
|
|
|
|
m_launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
|
|
|
|
|
|
|
|
|
|
// TODO readd information about packages? msgListFile(m_signedPackage)
|
|
|
|
|
appendMessage(tr("Deploying application to '%2'...").arg(m_serialPortFriendlyName), false);
|
|
|
|
|
|
|
|
|
|
QString errorMessage;
|
|
|
|
|
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);
|
|
|
|
|
reportError(errorMessage);
|
|
|
|
|
stop();
|
|
|
|
|
}
|
2011-01-25 09:18:45 +01:00
|
|
|
} else if (m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection) {
|
|
|
|
|
appendMessage(tr("Deploying application to '%1'...").arg(m_serialPortFriendlyName), false);
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice = SymbianUtils::SymbianDeviceManager::instance()->getTcfPort(m_serialPortName);
|
|
|
|
|
bool ok = m_codaDevice && m_codaDevice->device()->isOpen();
|
2011-01-25 09:18:45 +01:00
|
|
|
if (!ok) {
|
2011-02-04 12:08:19 +01:00
|
|
|
QString deviceError = tr("No such port");
|
2011-02-07 14:14:57 +01:00
|
|
|
if (m_codaDevice)
|
|
|
|
|
deviceError = m_codaDevice->device()->errorString();
|
2011-02-04 12:08:19 +01:00
|
|
|
reportError(tr("Couldn't open serial device: %1").arg(deviceError));
|
2011-01-25 09:18:45 +01:00
|
|
|
stop();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2011-02-04 12:08:19 +01:00
|
|
|
setupConnections();
|
2011-01-25 09:18:45 +01:00
|
|
|
m_state = StateConnecting;
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice->sendSerialPing(false);
|
2011-02-02 10:44:57 +01:00
|
|
|
QTimer::singleShot(4000, this, SLOT(checkForTimeout()));
|
2011-01-07 15:47:22 +01:00
|
|
|
} else {
|
2011-02-04 12:08:19 +01:00
|
|
|
m_codaDevice = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice);
|
|
|
|
|
setupConnections();
|
2011-02-07 14:26:34 +01:00
|
|
|
const QSharedPointer<QTcpSocket> codaSocket(new QTcpSocket);
|
2011-02-04 12:08:19 +01:00
|
|
|
m_codaDevice->setDevice(codaSocket);
|
2011-02-07 14:26:34 +01:00
|
|
|
codaSocket->connectToHost(m_address, m_port);
|
2011-01-07 15:47:22 +01:00
|
|
|
m_state = StateConnecting;
|
|
|
|
|
appendMessage(tr("Connecting to %1:%2...").arg(m_address).arg(m_port), false);
|
|
|
|
|
QTimer::singleShot(4000, this, SLOT(checkForTimeout()));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::run(QFutureInterface<bool> &fi)
|
|
|
|
|
{
|
|
|
|
|
m_futureInterface = &fi;
|
2010-08-05 15:25:01 +02:00
|
|
|
m_deployResult = true;
|
2011-01-07 15:47:22 +01:00
|
|
|
m_deployCanceled = false;
|
|
|
|
|
disconnect(this);
|
|
|
|
|
|
2011-01-31 16:22:37 +01:00
|
|
|
m_futureInterface->setProgressRange(0, 100*m_signedPackages.count());
|
|
|
|
|
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
|
2011-01-07 15:47:22 +01:00
|
|
|
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);
|
|
|
|
|
}
|
2010-07-15 13:58:18 +02:00
|
|
|
|
2011-01-31 16:22:37 +01:00
|
|
|
connect(this, SIGNAL(copyProgressChanged(int)), this, SLOT(updateProgress(int)));
|
|
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
start();
|
|
|
|
|
m_timer = new QTimer();
|
|
|
|
|
connect(m_timer, SIGNAL(timeout()), this, SLOT(checkForCancel()), Qt::DirectConnection);
|
|
|
|
|
m_timer->start(500);
|
|
|
|
|
m_eventLoop = new QEventLoop();
|
|
|
|
|
m_eventLoop->exec();
|
|
|
|
|
m_timer->stop();
|
|
|
|
|
delete m_timer;
|
|
|
|
|
m_timer = 0;
|
|
|
|
|
|
2011-02-07 14:14:57 +01:00
|
|
|
if (m_codaDevice) {
|
|
|
|
|
disconnect(m_codaDevice.data(), 0, this, 0);
|
|
|
|
|
SymbianUtils::SymbianDeviceManager::instance()->releaseTcfPort(m_codaDevice);
|
2011-02-04 12:08:19 +01:00
|
|
|
}
|
2011-01-07 15:47:22 +01:00
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
delete m_eventLoop;
|
|
|
|
|
m_eventLoop = 0;
|
|
|
|
|
fi.reportResult(m_deployResult);
|
|
|
|
|
m_futureInterface = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-07 15:47:22 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-07 14:26:34 +01:00
|
|
|
void S60DeployStep::slotCodaEvent (const Coda::CodaEvent &event)
|
2011-01-07 15:47:22 +01:00
|
|
|
{
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug() << "CODA event:" << "Type:" << event.type() << "Message:" << event.toString();
|
|
|
|
|
|
|
|
|
|
switch (event.type()) {
|
2011-02-07 14:26:34 +01:00
|
|
|
case Coda::CodaEvent::LocatorHello: {// Commands accepted now
|
2011-01-07 15:47:22 +01:00
|
|
|
m_state = StateConnected;
|
2011-02-02 10:44:57 +01:00
|
|
|
emit codaConnected();
|
2011-01-07 15:47:22 +01:00
|
|
|
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 =
|
2011-02-07 14:26:34 +01:00
|
|
|
Coda::CodaDevice::FileSystem_TCF_O_WRITE
|
|
|
|
|
|Coda::CodaDevice::FileSystem_TCF_O_CREAT
|
|
|
|
|
|Coda::CodaDevice::FileSystem_TCF_O_TRUNC;
|
2011-01-07 15:47:22 +01:00
|
|
|
m_putWriteOk = false;
|
|
|
|
|
|
|
|
|
|
QString packageName(QFileInfo(m_signedPackages.at(m_currentFileIndex)).fileName());
|
|
|
|
|
QString remoteFileLocation = QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(packageName);
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice->sendFileSystemOpenCommand(Coda::CodaCallback(this, &S60DeployStep::handleFileSystemOpen),
|
2011-01-07 15:47:22 +01:00
|
|
|
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) {
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice->sendSymbianInstallSilentInstallCommand(Coda::CodaCallback(this, &S60DeployStep::handleSymbianInstall),
|
2011-01-07 15:47:22 +01:00
|
|
|
remoteFileLocation.toAscii(), QString::fromLatin1("%1:").arg(m_installationDrive).toAscii());
|
|
|
|
|
appendMessage(tr("Installing package \"%1\" on drive %2:...").arg(packageName).arg(m_installationDrive), false);
|
|
|
|
|
} else {
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice->sendSymbianInstallUIInstallCommand(Coda::CodaCallback(this, &S60DeployStep::handleSymbianInstall),
|
2011-01-07 15:47:22 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-07 14:26:34 +01:00
|
|
|
void S60DeployStep::handleFileSystemOpen(const Coda::CodaCommandResult &result)
|
2011-01-07 15:47:22 +01:00
|
|
|
{
|
2011-02-07 14:26:34 +01:00
|
|
|
if (result.type != Coda::CodaCommandResult::SuccessReply) {
|
2011-01-07 15:47:22 +01:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-07 14:26:34 +01:00
|
|
|
void S60DeployStep::handleSymbianInstall(const Coda::CodaCommandResult &result)
|
2011-01-07 15:47:22 +01:00
|
|
|
{
|
2011-02-07 14:26:34 +01:00
|
|
|
if (result.type == Coda::CodaCommandResult::SuccessReply) {
|
2011-01-07 15:47:22 +01:00
|
|
|
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);
|
2011-01-31 16:22:37 +01:00
|
|
|
const quint64 size = m_putFile->size();
|
2011-01-07 15:47:22 +01:00
|
|
|
if (data.isEmpty()) {
|
|
|
|
|
m_putWriteOk = true;
|
|
|
|
|
closeRemoteFile();
|
2011-01-31 16:22:37 +01:00
|
|
|
setCopyProgress(100);
|
2011-01-07 15:47:22 +01:00
|
|
|
} else {
|
|
|
|
|
m_putLastChunkSize = data.size();
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug("Writing %llu bytes to remote file '%s' at %llu\n",
|
|
|
|
|
m_putLastChunkSize,
|
|
|
|
|
m_remoteFileHandle.constData(), pos);
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice->sendFileSystemWriteCommand(Coda::CodaCallback(this, &S60DeployStep::handleFileSystemWrite),
|
2011-01-07 15:47:22 +01:00
|
|
|
m_remoteFileHandle, data, unsigned(pos));
|
2011-01-31 16:22:37 +01:00
|
|
|
setCopyProgress((100*(m_putLastChunkSize+pos))/size);
|
2011-01-07 15:47:22 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::closeRemoteFile()
|
|
|
|
|
{
|
2011-02-07 14:14:57 +01:00
|
|
|
m_codaDevice->sendFileSystemCloseCommand(Coda::CodaCallback(this, &S60DeployStep::handleFileSystemClose),
|
2011-01-07 15:47:22 +01:00
|
|
|
m_remoteFileHandle);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-07 14:26:34 +01:00
|
|
|
void S60DeployStep::handleFileSystemWrite(const Coda::CodaCommandResult &result)
|
2011-01-07 15:47:22 +01:00
|
|
|
{
|
|
|
|
|
// 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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-07 14:26:34 +01:00
|
|
|
void S60DeployStep::handleFileSystemClose(const Coda::CodaCommandResult &result)
|
2011-01-07 15:47:22 +01:00
|
|
|
{
|
2011-02-07 14:26:34 +01:00
|
|
|
if (result.type == Coda::CodaCommandResult::SuccessReply) {
|
2011-01-07 15:47:22 +01:00
|
|
|
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()
|
|
|
|
|
{
|
2011-01-21 17:30:02 +01:00
|
|
|
if (m_state != StateConnecting)
|
2011-01-07 15:47:22 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const QString title = tr("Waiting for CODA");
|
2011-02-02 10:44:57 +01:00
|
|
|
const QString text = tr("Qt Creator is waiting for the CODA application to connect."
|
|
|
|
|
"\nPlease make sure the application is running on "
|
|
|
|
|
"your mobile phone and the right IP address or serial port is "
|
2011-01-07 15:47:22 +01:00
|
|
|
"configured in the project settings.");
|
|
|
|
|
QMessageBox *mb = new QMessageBox(QMessageBox::Information, title, text,
|
|
|
|
|
QMessageBox::Cancel, Core::ICore::instance()->mainWindow());
|
2011-02-02 10:44:57 +01:00
|
|
|
connect(this, SIGNAL(codaConnected()), mb, SLOT(close()));
|
2011-01-07 15:47:22 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
void S60DeployStep::setReleaseDeviceAfterLauncherFinish(bool v)
|
|
|
|
|
{
|
|
|
|
|
m_releaseDeviceAfterLauncherFinish = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::slotLauncherStateChanged(int s)
|
|
|
|
|
{
|
|
|
|
|
if (s == trk::Launcher::WaitingForTrk) {
|
2011-01-18 16:45:42 +01:00
|
|
|
QMessageBox *mb = TrkRunControl::createTrkWaitingMessageBox(m_launcher->trkServerName(),
|
2011-01-07 15:47:22 +01:00
|
|
|
Core::ICore::instance()->mainWindow());
|
2010-07-15 13:58:18 +02:00
|
|
|
connect(m_launcher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
|
2011-01-18 16:45:42 +01:00
|
|
|
connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed()));
|
2010-07-15 13:58:18 +02:00
|
|
|
mb->open();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::slotWaitingForTrkClosed()
|
|
|
|
|
{
|
2011-01-18 16:45:42 +01:00
|
|
|
if (m_launcher && m_launcher->state() == trk::Launcher::WaitingForTrk)
|
|
|
|
|
m_deployCanceled = true;
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-05 15:25:01 +02:00
|
|
|
void S60DeployStep::createFileFailed(const QString &filename, const QString &errorMessage)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
reportError(tr("Could not create file %1 on device: %2").arg(filename, errorMessage));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-05 15:25:01 +02:00
|
|
|
void S60DeployStep::writeFileFailed(const QString &filename, const QString &errorMessage)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
reportError(tr("Could not write to file %1 on device: %2").arg(filename, errorMessage));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-05 15:25:01 +02:00
|
|
|
void S60DeployStep::closeFileFailed(const QString &filename, const QString &errorMessage)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
|
|
|
|
const QString msg = tr("Could not close file %1 on device: %2. It will be closed when App TRK is closed.");
|
2011-01-07 15:47:22 +01:00
|
|
|
reportError( msg.arg(filename, errorMessage));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-05 15:25:01 +02:00
|
|
|
void S60DeployStep::connectFailed(const QString &errorMessage)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
reportError(tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-09-09 13:43:29 +02:00
|
|
|
void S60DeployStep::printCopyingNotice(const QString &fileName)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-09-09 13:43:29 +02:00
|
|
|
appendMessage(tr("Copying \"%1\"...").arg(fileName), false);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-09-09 13:43:29 +02:00
|
|
|
void S60DeployStep::printInstallingNotice(const QString &packageName)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-09-09 13:43:29 +02:00
|
|
|
appendMessage(tr("Installing package \"%1\" on drive %2:...").arg(packageName).arg(m_installationDrive), false);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::printInstallingFinished()
|
|
|
|
|
{
|
|
|
|
|
appendMessage(tr("Installation has finished"), false);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-05 15:25:01 +02:00
|
|
|
void S60DeployStep::installFailed(const QString &filename, const QString &errorMessage)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
reportError(tr("Could not install from package %1 on device: %2").arg(filename, errorMessage));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::checkForCancel()
|
|
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
if ((m_futureInterface->isCanceled() || m_deployCanceled) && m_timer->isActive()) {
|
2010-07-15 13:58:18 +02:00
|
|
|
m_timer->stop();
|
|
|
|
|
stop();
|
2011-01-07 15:47:22 +01:00
|
|
|
QString canceledText(tr("Deployment has been cancelled."));
|
|
|
|
|
appendMessage(canceledText, true);
|
|
|
|
|
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
|
|
|
|
|
canceledText,
|
|
|
|
|
QString(), -1,
|
|
|
|
|
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
|
|
|
|
emit finishNow(false);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-07 15:47:22 +01:00
|
|
|
void S60DeployStep::launcherFinished(bool success)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
m_deployResult = success;
|
2011-01-31 16:22:37 +01:00
|
|
|
if(m_deployResult && m_futureInterface)
|
|
|
|
|
m_futureInterface->setProgressValue(m_futureInterface->progressMaximum());
|
2010-07-15 13:58:18 +02:00
|
|
|
if (m_releaseDeviceAfterLauncherFinish && m_launcher) {
|
|
|
|
|
m_handleDeviceRemoval = false;
|
|
|
|
|
trk::Launcher::releaseToDeviceManager(m_launcher);
|
|
|
|
|
}
|
2011-01-07 15:47:22 +01:00
|
|
|
if (m_launcher)
|
2010-07-15 13:58:18 +02:00
|
|
|
m_launcher->deleteLater();
|
|
|
|
|
m_launcher = 0;
|
2011-01-07 15:47:22 +01:00
|
|
|
if (m_eventLoop)
|
|
|
|
|
m_eventLoop->exit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::deploymentFinished(bool success)
|
|
|
|
|
{
|
|
|
|
|
m_deployResult = success;
|
2011-01-31 16:22:37 +01:00
|
|
|
if(m_deployResult && m_futureInterface)
|
|
|
|
|
m_futureInterface->setProgressValue(m_futureInterface->progressMaximum());
|
2011-01-07 15:47:22 +01:00
|
|
|
if (m_eventLoop)
|
2010-08-05 15:25:01 +02:00
|
|
|
m_eventLoop->exit();
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::deviceRemoved(const SymbianUtils::SymbianDevice &d)
|
|
|
|
|
{
|
2011-01-07 15:47:22 +01:00
|
|
|
if (m_handleDeviceRemoval && d.portName() == m_serialPortName)
|
|
|
|
|
reportError(tr("The device '%1' has been disconnected").arg(d.friendlyName()));
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2011-01-31 16:22:37 +01:00
|
|
|
void S60DeployStep::setCopyProgress(int progress)
|
|
|
|
|
{
|
|
|
|
|
if (progress < 0)
|
|
|
|
|
progress = 0;
|
|
|
|
|
else if (progress > 100)
|
|
|
|
|
progress = 100;
|
|
|
|
|
if (copyProgress() == progress)
|
|
|
|
|
return;
|
|
|
|
|
m_copyProgress = progress;
|
|
|
|
|
emit copyProgressChanged(m_copyProgress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int S60DeployStep::copyProgress() const
|
|
|
|
|
{
|
|
|
|
|
return m_copyProgress;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S60DeployStep::updateProgress(int progress)
|
|
|
|
|
{
|
|
|
|
|
//This would show the percentage on the Compile output
|
|
|
|
|
//appendMessage(tr("Copy percentage: %1%").arg((m_currentFileIndex*100 + progress) /m_signedPackages.count()), false);
|
|
|
|
|
int copyProgress = ((m_currentFileIndex*100 + progress) /m_signedPackages.count());
|
|
|
|
|
int entireProgress = copyProgress * 0.8; //the copy progress is just 80% of the whole deployment progress
|
|
|
|
|
m_futureInterface->setProgressValueAndText(entireProgress, tr("Copy percentage: %1%").arg(copyProgress));
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
// #pragma mark -- S60DeployStepWidget
|
|
|
|
|
|
|
|
|
|
BuildStepConfigWidget *S60DeployStep::createConfigWidget()
|
|
|
|
|
{
|
|
|
|
|
return new S60DeployStepWidget();
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-03 10:03:48 +01:00
|
|
|
S60DeployStepWidget::S60DeployStepWidget() : ProjectExplorer::BuildStepConfigWidget()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-15 13:58:18 +02:00
|
|
|
void S60DeployStepWidget::init()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString S60DeployStepWidget::summaryText() const
|
|
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
return QString("<b>%1</b>").arg(displayName());
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString S60DeployStepWidget::displayName() const
|
|
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
return tr("Deploy SIS Package");
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #pragma mark -- S60DeployStepFactory
|
|
|
|
|
|
|
|
|
|
S60DeployStepFactory::S60DeployStepFactory(QObject *parent) :
|
2011-01-07 15:47:22 +01:00
|
|
|
ProjectExplorer::IBuildStepFactory(parent)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
S60DeployStepFactory::~S60DeployStepFactory()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
bool S60DeployStepFactory::canCreate(ProjectExplorer::BuildStepList *parent, const QString &id) const
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
if (parent->id() != QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY))
|
2010-07-15 13:58:18 +02:00
|
|
|
return false;
|
|
|
|
|
if (parent->target()->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
|
|
|
|
|
return false;
|
|
|
|
|
return (id == QLatin1String(S60_DEPLOY_STEP_ID));
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
ProjectExplorer::BuildStep *S60DeployStepFactory::create(ProjectExplorer::BuildStepList *parent, const QString &id)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
if (!canCreate(parent, id))
|
2010-07-15 13:58:18 +02:00
|
|
|
return 0;
|
2010-07-16 14:00:41 +02:00
|
|
|
return new S60DeployStep(parent);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
bool S60DeployStepFactory::canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source) const
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
if (!canCreate(parent, source->id()))
|
|
|
|
|
return false;
|
|
|
|
|
if (!qobject_cast<S60DeployStep *>(source))
|
|
|
|
|
return false;
|
|
|
|
|
return true;
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
ProjectExplorer::BuildStep *S60DeployStepFactory::clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
if (!canClone(parent, source))
|
2010-07-15 13:58:18 +02:00
|
|
|
return 0;
|
|
|
|
|
return new S60DeployStep(parent, static_cast<S60DeployStep *>(source));
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
bool S60DeployStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
|
|
|
|
QString id(ProjectExplorer::idFromMap(map));
|
2010-07-16 14:00:41 +02:00
|
|
|
return canCreate(parent, id);
|
2010-07-15 13:58:18 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
ProjectExplorer::BuildStep *S60DeployStepFactory::restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map)
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
if (!canRestore(parent, map))
|
2010-07-15 13:58:18 +02:00
|
|
|
return 0;
|
|
|
|
|
S60DeployStep *bs = new S60DeployStep(parent);
|
|
|
|
|
if (bs->fromMap(map))
|
|
|
|
|
return bs;
|
|
|
|
|
delete bs;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-16 14:00:41 +02:00
|
|
|
QStringList S60DeployStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
|
2010-07-15 13:58:18 +02:00
|
|
|
{
|
2010-07-16 14:00:41 +02:00
|
|
|
if (parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
|
2011-01-07 15:47:22 +01:00
|
|
|
&& parent->target()->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID))
|
2010-07-15 13:58:18 +02:00
|
|
|
return QStringList() << QLatin1String(S60_DEPLOY_STEP_ID);
|
|
|
|
|
return QStringList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString S60DeployStepFactory::displayNameForId(const QString &id) const
|
|
|
|
|
{
|
|
|
|
|
if (id == QLatin1String(S60_DEPLOY_STEP_ID))
|
|
|
|
|
return tr("Deploy SIS Package");
|
|
|
|
|
return QString();
|
|
|
|
|
}
|