tools/runonphone/symbianutils/launcher.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
    42 #include "launcher.h"
    42 #include "launcher.h"
    43 #include "trkutils.h"
    43 #include "trkutils.h"
    44 #include "trkutils_p.h"
    44 #include "trkutils_p.h"
    45 #include "trkdevice.h"
    45 #include "trkdevice.h"
    46 #include "bluetoothlistener.h"
    46 #include "bluetoothlistener.h"
       
    47 #include "symbiandevicemanager.h"
    47 
    48 
    48 #include <QtCore/QTimer>
    49 #include <QtCore/QTimer>
    49 #include <QtCore/QDateTime>
    50 #include <QtCore/QDateTime>
    50 #include <QtCore/QVariant>
    51 #include <QtCore/QVariant>
    51 #include <QtCore/QDebug>
    52 #include <QtCore/QDebug>
    52 #include <QtCore/QQueue>
    53 #include <QtCore/QQueue>
    53 #include <QtCore/QFile>
    54 #include <QtCore/QFile>
    54 #include <QtCore/QScopedPointer>
    55 #include <QtCore/QScopedPointer>
    55 
    56 
       
    57 #include <cstdio>
       
    58 
    56 namespace trk {
    59 namespace trk {
    57 
    60 
    58 struct LauncherPrivate {
    61 struct LauncherPrivate {
    59     struct CopyState {
    62     struct CopyState {
    60         QString sourceFileName;
    63         QString sourceFileName;
    61         QString destinationFileName;
    64         QString destinationFileName;
    62         uint copyFileHandle;
    65         uint copyFileHandle;
    63         QScopedPointer<QByteArray> data;
    66         QScopedPointer<QByteArray> data;
    64         int position;
    67         qint64 position;
       
    68         QScopedPointer<QFile> localFile;
    65     };
    69     };
    66 
    70 
    67     explicit LauncherPrivate(const TrkDevicePtr &d);
    71     explicit LauncherPrivate(const TrkDevicePtr &d);
    68 
    72 
    69     TrkDevicePtr m_device;
    73     TrkDevicePtr m_device;
    73     void logMessage(const QString &msg);
    77     void logMessage(const QString &msg);
    74     // Debuggee state
    78     // Debuggee state
    75     Session m_session; // global-ish data (process id, target information)
    79     Session m_session; // global-ish data (process id, target information)
    76 
    80 
    77     CopyState m_copyState;
    81     CopyState m_copyState;
       
    82     CopyState m_downloadState;
    78     QString m_fileName;
    83     QString m_fileName;
    79     QStringList m_commandLineArgs;
    84     QStringList m_commandLineArgs;
    80     QString m_installFileName;
    85     QString m_installFileName;
    81     int m_verbose;
    86     int m_verbose;
    82     Launcher::Actions m_startupActions;
    87     Launcher::Actions m_startupActions;
    98                    QObject *parent) :
   103                    QObject *parent) :
    99     QObject(parent),
   104     QObject(parent),
   100     d(new LauncherPrivate(dev))
   105     d(new LauncherPrivate(dev))
   101 {
   106 {
   102     d->m_startupActions = startupActions;
   107     d->m_startupActions = startupActions;
   103     connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));    
   108     connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));
   104     connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close()));
       
   105 }
   109 }
   106 
   110 
   107 Launcher::~Launcher()
   111 Launcher::~Launcher()
   108 {
   112 {
       
   113     // Destroyed before protocol was through: Close
       
   114     if (d->m_closeDevice && d->m_device->isOpen())
       
   115         d->m_device->close();
       
   116     emit destroyed(d->m_device->port());
   109     logMessage("Shutting down.\n");
   117     logMessage("Shutting down.\n");
   110     delete d;
   118     delete d;
   111 }
   119 }
   112 
   120 
   113 Launcher::State Launcher::state() const
   121 Launcher::State Launcher::state() const
   152 {
   160 {
   153     d->m_copyState.sourceFileName = srcName;
   161     d->m_copyState.sourceFileName = srcName;
   154     d->m_copyState.destinationFileName = dstName;
   162     d->m_copyState.destinationFileName = dstName;
   155 }
   163 }
   156 
   164 
       
   165 void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName)
       
   166 {
       
   167     d->m_downloadState.sourceFileName = srcName;
       
   168     d->m_downloadState.destinationFileName = dstName;
       
   169 }
       
   170 
   157 void Launcher::setInstallFileName(const QString &name)
   171 void Launcher::setInstallFileName(const QString &name)
   158 {
   172 {
   159     d->m_installFileName = name;
   173     d->m_installFileName = name;
   160 }
   174 }
   161 
   175 
   187 
   201 
   188 bool Launcher::startServer(QString *errorMessage)
   202 bool Launcher::startServer(QString *errorMessage)
   189 {
   203 {
   190     errorMessage->clear();
   204     errorMessage->clear();
   191     if (d->m_verbose) {
   205     if (d->m_verbose) {
   192         const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6")
   206         QString msg;
   193                             .arg(trkServerName(), d->m_fileName,
   207         QTextStream str(&msg);
   194                                  d->m_commandLineArgs.join(QString(QLatin1Char(' '))),
   208         str.setIntegerBase(16);
   195                                  d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName);
   209         str << "Actions=0x" << d->m_startupActions;
       
   210         str.setIntegerBase(10);
       
   211         str << " Port=" << trkServerName();
       
   212         if (!d->m_fileName.isEmpty())
       
   213             str << " Executable=" << d->m_fileName;
       
   214         if (!d->m_commandLineArgs.isEmpty())
       
   215             str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' ')));
       
   216         if (!d->m_copyState.sourceFileName.isEmpty())
       
   217             str << " Package/Source=" << d->m_copyState.sourceFileName;
       
   218         if (!d->m_copyState.destinationFileName.isEmpty())
       
   219             str << " Remote Package/Destination=" << d->m_copyState.destinationFileName;
       
   220         if (!d->m_downloadState.sourceFileName.isEmpty())
       
   221             str << " Source=" << d->m_downloadState.sourceFileName;
       
   222         if (!d->m_downloadState.destinationFileName.isEmpty())
       
   223             str << " Destination=" << d->m_downloadState.destinationFileName;
       
   224         if (!d->m_installFileName.isEmpty())
       
   225             str << " Install file=" << d->m_installFileName;
   196         logMessage(msg);
   226         logMessage(msg);
   197     }
   227     }
   198     if (d->m_startupActions & ActionCopy) {
   228     if (d->m_startupActions & ActionCopy) {
   199         if (d->m_copyState.sourceFileName.isEmpty()) {
   229         if (d->m_copyState.sourceFileName.isEmpty()) {
   200             qWarning("No local filename given for copying package.");
   230             qWarning("No local filename given for copying package.");
   212         qWarning("No remote executable given for running.");
   242         qWarning("No remote executable given for running.");
   213         return false;
   243         return false;
   214     }
   244     }
   215     if (!d->m_device->isOpen() && !d->m_device->open(errorMessage))
   245     if (!d->m_device->isOpen() && !d->m_device->open(errorMessage))
   216         return false;
   246         return false;
   217     if (d->m_closeDevice) {
       
   218         connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close()));
       
   219     } else {
       
   220         disconnect(this, SIGNAL(finished()), d->m_device.data(), 0);
       
   221     }
       
   222     setState(Connecting);
   247     setState(Connecting);
   223     // Set up the temporary 'waiting' state if we do not get immediate connection
   248     // Set up the temporary 'waiting' state if we do not get immediate connection
   224     QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk()));
   249     QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk()));
   225     d->m_device->sendTrkInitialPing();
   250     d->m_device->sendTrkInitialPing();
   226     d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected
   251     d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected
   250         copyFileToRemote();
   275         copyFileToRemote();
   251     else if (d->m_startupActions & ActionInstall)
   276     else if (d->m_startupActions & ActionInstall)
   252         installRemotePackageSilently();
   277         installRemotePackageSilently();
   253     else if (d->m_startupActions & ActionRun)
   278     else if (d->m_startupActions & ActionRun)
   254         startInferiorIfNeeded();
   279         startInferiorIfNeeded();
       
   280     else if (d->m_startupActions & ActionDownload)
       
   281         copyFileFromRemote();
   255 }
   282 }
   256 
   283 
   257 void Launcher::setVerbose(int v)
   284 void Launcher::setVerbose(int v)
   258 {
   285 {
   259     d->m_verbose = v;
   286     d->m_verbose = v;
   262 
   289 
   263 void Launcher::logMessage(const QString &msg)
   290 void Launcher::logMessage(const QString &msg)
   264 {
   291 {
   265     if (d->m_verbose)
   292     if (d->m_verbose)
   266         qDebug() << "LAUNCHER: " << qPrintable(msg);
   293         qDebug() << "LAUNCHER: " << qPrintable(msg);
       
   294 }
       
   295 
       
   296 void Launcher::handleFinished()
       
   297 {
       
   298     if (d->m_closeDevice)
       
   299         d->m_device->close();
       
   300     emit finished();
   267 }
   301 }
   268 
   302 
   269 void Launcher::terminate()
   303 void Launcher::terminate()
   270 {
   304 {
   271     switch (state()) {
   305     switch (state()) {
   285     case Disconnected:
   319     case Disconnected:
   286         break;
   320         break;
   287     case Connecting:
   321     case Connecting:
   288     case WaitingForTrk:
   322     case WaitingForTrk:
   289         setState(Disconnected);
   323         setState(Disconnected);
   290         emit finished();
   324         handleFinished();
   291         break;
   325         break;
   292     }
   326     }
   293 }
   327 }
   294 
   328 
   295 void Launcher::handleRemoteProcessKilled(const TrkResult &result)
   329 void Launcher::handleRemoteProcessKilled(const TrkResult &result)
   329 void Launcher::handleResult(const TrkResult &result)
   363 void Launcher::handleResult(const TrkResult &result)
   330 {
   364 {
   331     QByteArray prefix = "READ BUF:                                       ";
   365     QByteArray prefix = "READ BUF:                                       ";
   332     QByteArray str = result.toString().toUtf8();
   366     QByteArray str = result.toString().toUtf8();
   333     if (result.isDebugOutput) { // handle application output
   367     if (result.isDebugOutput) { // handle application output
   334         logMessage("APPLICATION OUTPUT: " + result.data);
   368         QString msg;
   335         emit applicationOutputReceived(result.data);
   369         if (result.multiplex == MuxTextTrace) {
       
   370             if (result.data.length() > 8) {
       
   371             quint64 timestamp = extractInt64(result.data) & 0x0FFFFFFFFFFFFFFFULL;
       
   372             quint64 secs = timestamp / 1000000000;
       
   373             quint64 ns = timestamp % 1000000000;
       
   374             msg = QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.data.mid(8)));
       
   375             logMessage("TEXT TRACE: " + msg);
       
   376             }
       
   377         } else {
       
   378             logMessage("APPLICATION OUTPUT: " + result.data);
       
   379             msg = result.data;
       
   380         }
       
   381         msg.replace("\r\n", "\n");
       
   382         if(!msg.endsWith('\n')) msg.append('\n');
       
   383         emit applicationOutputReceived(msg);
   336         return;
   384         return;
   337     }
   385     }
   338     switch (result.code) {
   386     switch (result.code) {
   339         case TrkNotifyAck:
   387         case TrkNotifyAck:
   340             break;
   388             break;
   408                        arg(name));
   456                        arg(name));
   409             d->m_device->sendTrkAck(result.token);
   457             d->m_device->sendTrkAck(result.token);
   410             if (itemType == 0 // process
   458             if (itemType == 0 // process
   411                 && result.data.size() >= 10
   459                 && result.data.size() >= 10
   412                 && d->m_session.pid == extractInt(result.data.data() + 6)) {
   460                 && d->m_session.pid == extractInt(result.data.data() + 6)) {
   413                 disconnectTrk();
   461                     copyFileFromRemote();
   414             }
   462             }
   415             break;
   463             break;
   416         }
   464         }
   417         case TrkNotifyProcessorStarted: { // NotifyProcessorStarted
   465         case TrkNotifyProcessorStarted: { // NotifyProcessorStarted
   418             logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str);
   466             logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str);
   444 void Launcher::handleTrkVersion(const TrkResult &result)
   492 void Launcher::handleTrkVersion(const TrkResult &result)
   445 {
   493 {
   446     if (result.errorCode() || result.data.size() < 5) {
   494     if (result.errorCode() || result.data.size() < 5) {
   447         if (d->m_startupActions == ActionPingOnly) {
   495         if (d->m_startupActions == ActionPingOnly) {
   448             setState(Disconnected);
   496             setState(Disconnected);
   449             emit finished();
   497             handleFinished();
   450         }
   498         }
   451         return;
   499         return;
   452     }
   500     }
   453     d->m_session.trkAppVersion.trkMajor = result.data.at(1);
   501     d->m_session.trkAppVersion.trkMajor = result.data.at(1);
   454     d->m_session.trkAppVersion.trkMinor = result.data.at(2);
   502     d->m_session.trkAppVersion.trkMinor = result.data.at(2);
   455     d->m_session.trkAppVersion.protocolMajor = result.data.at(3);
   503     d->m_session.trkAppVersion.protocolMajor = result.data.at(3);
   456     d->m_session.trkAppVersion.protocolMinor = result.data.at(4);
   504     d->m_session.trkAppVersion.protocolMinor = result.data.at(4);
   457     setState(DeviceDescriptionReceived);
   505     setState(DeviceDescriptionReceived);
       
   506     const QString msg = deviceDescription();
       
   507     emit deviceDescriptionReceived(trkServerName(), msg);
   458     // Ping mode: Log & Terminate
   508     // Ping mode: Log & Terminate
   459     if (d->m_startupActions == ActionPingOnly) {
   509     if (d->m_startupActions == ActionPingOnly) {
   460         qWarning("%s", qPrintable(deviceDescription()));
   510         qWarning("%s", qPrintable(msg));
   461         setState(Disconnected);
   511         setState(Disconnected);
   462         emit finished();
   512         handleFinished();
   463     }
   513     }
       
   514 }
       
   515 
       
   516 static inline QString msgCannotOpenRemoteFile(const QString &fileName, const QString &message)
       
   517 {
       
   518     return Launcher::tr("Cannot open remote file '%1': %2").arg(fileName, message);
       
   519 }
       
   520 
       
   521 static inline QString msgCannotOpenLocalFile(const QString &fileName, const QString &message)
       
   522 {
       
   523     return Launcher::tr("Cannot open '%1': %2").arg(fileName, message);
   464 }
   524 }
   465 
   525 
   466 void Launcher::handleFileCreation(const TrkResult &result)
   526 void Launcher::handleFileCreation(const TrkResult &result)
   467 {
   527 {
   468     if (result.errorCode() || result.data.size() < 6) {
   528     if (result.errorCode() || result.data.size() < 6) {
   469         emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString());
   529         const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString());
       
   530         logMessage(msg);
       
   531         emit canNotCreateFile(d->m_copyState.destinationFileName, msg);
   470         disconnectTrk();
   532         disconnectTrk();
   471         return;
   533         return;
   472     }
   534     }
   473     const char *data = result.data.data();
   535     const char *data = result.data.data();
   474     d->m_copyState.copyFileHandle = extractInt(data + 2);
   536     d->m_copyState.copyFileHandle = extractInt(data + 2);
   475     QFile file(d->m_copyState.sourceFileName);
   537     const QString localFileName = d->m_copyState.sourceFileName;
   476     file.open(QIODevice::ReadOnly);
   538     QFile file(localFileName);
       
   539     d->m_copyState.position = 0;
       
   540     if (!file.open(QIODevice::ReadOnly)) {
       
   541         const QString msg = msgCannotOpenLocalFile(localFileName, file.errorString());
       
   542         logMessage(msg);
       
   543         emit canNotOpenLocalFile(localFileName, msg);
       
   544         closeRemoteFile(true);
       
   545         disconnectTrk();
       
   546         return;
       
   547     }
   477     d->m_copyState.data.reset(new QByteArray(file.readAll()));
   548     d->m_copyState.data.reset(new QByteArray(file.readAll()));
   478     d->m_copyState.position = 0;
       
   479     file.close();
   549     file.close();
   480     continueCopying();
   550     continueCopying();
       
   551 }
       
   552 
       
   553 void Launcher::handleFileOpened(const TrkResult &result)
       
   554 {
       
   555     if (result.errorCode() || result.data.size() < 6) {
       
   556         const QString msg = msgCannotOpenRemoteFile(d->m_downloadState.sourceFileName, result.errorString());
       
   557         logMessage(msg);
       
   558         emit canNotOpenFile(d->m_downloadState.sourceFileName, msg);
       
   559         disconnectTrk();
       
   560         return;
       
   561     }
       
   562     d->m_downloadState.position = 0;
       
   563     const QString localFileName = d->m_downloadState.destinationFileName;
       
   564     bool opened = false;
       
   565     if (localFileName == QLatin1String("-")) {
       
   566         d->m_downloadState.localFile.reset(new QFile);
       
   567         opened = d->m_downloadState.localFile->open(stdout, QFile::WriteOnly);
       
   568     } else {
       
   569         d->m_downloadState.localFile.reset(new QFile(localFileName));
       
   570         opened = d->m_downloadState.localFile->open(QFile::WriteOnly | QFile::Truncate);
       
   571     }
       
   572     if (!opened) {
       
   573         const QString msg = msgCannotOpenLocalFile(localFileName, d->m_downloadState.localFile->errorString());
       
   574         logMessage(msg);
       
   575         emit canNotOpenLocalFile(localFileName, msg);
       
   576         closeRemoteFile(true);
       
   577         disconnectTrk();
       
   578     }
       
   579     continueReading();
       
   580 }
       
   581 
       
   582 void Launcher::continueReading()
       
   583 {
       
   584     QByteArray ba;
       
   585     appendInt(&ba, d->m_downloadState.copyFileHandle, TargetByteOrder);
       
   586     appendShort(&ba, 2048, TargetByteOrder);
       
   587     d->m_device->sendTrkMessage(TrkReadFile, TrkCallback(this, &Launcher::handleRead), ba);
       
   588 }
       
   589 
       
   590 void Launcher::handleRead(const TrkResult &result)
       
   591 {
       
   592     if (result.errorCode() || result.data.size() < 4) {
       
   593         d->m_downloadState.localFile->close();
       
   594         closeRemoteFile(true);
       
   595         disconnectTrk();
       
   596     } else {
       
   597         int length = extractShort(result.data.data() + 2);
       
   598         //TRK doesn't tell us the file length, so we need to keep reading until it returns 0 length
       
   599         if (length > 0) {
       
   600             d->m_downloadState.localFile->write(result.data.data() + 4, length);
       
   601             continueReading();
       
   602         } else {
       
   603             closeRemoteFile(true);
       
   604             disconnectTrk();
       
   605         }
       
   606     }
   481 }
   607 }
   482 
   608 
   483 void Launcher::handleCopy(const TrkResult &result)
   609 void Launcher::handleCopy(const TrkResult &result)
   484 {
   610 {
   485     if (result.errorCode() || result.data.size() < 4) {
   611     if (result.errorCode() || result.data.size() < 4) {
   491     }
   617     }
   492 }
   618 }
   493 
   619 
   494 void Launcher::continueCopying(uint lastCopiedBlockSize)
   620 void Launcher::continueCopying(uint lastCopiedBlockSize)
   495 {
   621 {
   496     int size = d->m_copyState.data->length();
   622     qint64 size = d->m_copyState.data->length();
   497     d->m_copyState.position += lastCopiedBlockSize;
   623     d->m_copyState.position += lastCopiedBlockSize;
   498     if (size == 0)
   624     if (size == 0)
   499         emit copyProgress(100);
   625         emit copyProgress(100);
   500     else {
   626     else {
   501         int percent = qMin((d->m_copyState.position*100)/size, 100);
   627         const qint64 hundred = 100;
   502         emit copyProgress(percent);
   628         const qint64 percent = qMin( (d->m_copyState.position * hundred) / size, hundred);
       
   629         emit copyProgress(static_cast<int>(percent));
   503     }
   630     }
   504     if (d->m_copyState.position < size) {
   631     if (d->m_copyState.position < size) {
   505         QByteArray ba;
   632         QByteArray ba;
   506         appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder);
   633         appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder);
   507         appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false);
   634         appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false);
   530         emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString());
   657         emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString());
   531     if (d->m_startupActions & ActionInstall)
   658     if (d->m_startupActions & ActionInstall)
   532         installRemotePackageSilently();
   659         installRemotePackageSilently();
   533     else if (d->m_startupActions & ActionRun)
   660     else if (d->m_startupActions & ActionRun)
   534         startInferiorIfNeeded();
   661         startInferiorIfNeeded();
       
   662     else if (d->m_startupActions & ActionDownload)
       
   663         copyFileFromRemote();
   535     else
   664     else
   536         disconnectTrk();
   665         disconnectTrk();
   537 }
   666 }
   538 
   667 
   539 void Launcher::handleCpuType(const TrkResult &result)
   668 void Launcher::handleCpuType(const TrkResult &result)
   584 
   713 
   585 void Launcher::handleWaitForFinished(const TrkResult &result)
   714 void Launcher::handleWaitForFinished(const TrkResult &result)
   586 {
   715 {
   587     logMessage("   FINISHED: " + stringFromArray(result.data));
   716     logMessage("   FINISHED: " + stringFromArray(result.data));
   588     setState(Disconnected);
   717     setState(Disconnected);
   589     emit finished();
   718     handleFinished();
   590 }
   719 }
   591 
   720 
   592 void Launcher::handleSupportMask(const TrkResult &result)
   721 void Launcher::handleSupportMask(const TrkResult &result)
   593 {
   722 {
   594     if (result.errorCode() || result.data.size() < 32)
   723     if (result.errorCode() || result.data.size() < 32)
   595         return;
   724         return;
   596     const char *data = result.data.data() + 1;
   725     const char *data = result.data.data() + 1;
   597 
   726 
   598     QString str = QLatin1String("SUPPORTED: ");
   727     if (d->m_verbose > 1) {
   599     for (int i = 0; i < 32; ++i) {
   728         QString str = QLatin1String("SUPPORTED: ");
   600         //str.append("  [" + formatByte(data[i]) + "]: ");
   729         for (int i = 0; i < 32; ++i) {
   601         for (int j = 0; j < 8; ++j) {
   730             for (int j = 0; j < 8; ++j) {
   602             if (data[i] & (1 << j)) {
   731                 if (data[i] & (1 << j)) {
   603                 str.append(QString::number(i * 8 + j, 16));
   732                     str.append(QString::number(i * 8 + j, 16));
   604                 str.append(QLatin1Char(' '));
   733                     str.append(QLatin1Char(' '));
       
   734                 }
   605             }
   735             }
   606         }
   736         }
   607     }
   737         logMessage(str);
   608     logMessage(str);
   738     }
   609 }
   739 }
   610 
   740 
   611 void Launcher::cleanUp()
   741 void Launcher::cleanUp()
   612 {
   742 {
   613     //
   743     //
   667 
   797 
   668 void Launcher::copyFileToRemote()
   798 void Launcher::copyFileToRemote()
   669 {
   799 {
   670     emit copyingStarted();
   800     emit copyingStarted();
   671     QByteArray ba;
   801     QByteArray ba;
   672     ba.append(char(10));
   802     ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary
   673     appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false);
   803     appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false);
   674     d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba);
   804     d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba);
       
   805 }
       
   806 
       
   807 void Launcher::copyFileFromRemote()
       
   808 {
       
   809     emit copyingStarted();
       
   810     QByteArray ba;
       
   811     ba.append(char(9)); //kDSFileOpenRead | kDSFileOpenBinary
       
   812     appendString(&ba, d->m_downloadState.sourceFileName.toLocal8Bit(), TargetByteOrder, false);
       
   813     d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileOpened), ba);
   675 }
   814 }
   676 
   815 
   677 void Launcher::installRemotePackageSilently()
   816 void Launcher::installRemotePackageSilently()
   678 {
   817 {
   679     emit installingStarted();
   818     emit installingStarted();
   692     } else {
   831     } else {
   693         emit installingFinished();
   832         emit installingFinished();
   694     }
   833     }
   695     if (d->m_startupActions & ActionRun) {
   834     if (d->m_startupActions & ActionRun) {
   696         startInferiorIfNeeded();
   835         startInferiorIfNeeded();
       
   836     } else if (d->m_startupActions & ActionDownload) {
       
   837         copyFileFromRemote();
   697     } else {
   838     } else {
   698         disconnectTrk();
   839         disconnectTrk();
   699     }
   840     }
   700 }
   841 }
   701 
   842 
   702 QByteArray Launcher::startProcessMessage(const QString &executable,
   843 QByteArray Launcher::startProcessMessage(const QString &executable,
   703                                          const QStringList &arguments)
   844                                          const QStringList &arguments)
   704 {
   845 {
   705     // It's not started yet
   846     // It's not started yet
   706     QByteArray ba;
   847     QByteArray ba;
   707     appendShort(&ba, 0, TargetByteOrder); // create new process
   848     appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem)
   708     ba.append(char(0)); // options - currently unused
   849     ba.append(char(0)); // options - currently unused
   709     if(arguments.isEmpty()) {
   850     // One string consisting of binary terminated by '\0' and arguments terminated by '\0'
   710         appendString(&ba, executable.toLocal8Bit(), TargetByteOrder);
   851     QByteArray commandLineBa = executable.toLocal8Bit();
   711         return ba;
   852     commandLineBa.append(char(0));
   712     }
   853     if (!arguments.isEmpty())
   713     // Append full command line as one string (leading length information).
   854         commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
   714     QByteArray commandLineBa;
   855     appendString(&ba, commandLineBa, TargetByteOrder, true);
   715     commandLineBa.append(executable.toLocal8Bit());
       
   716     commandLineBa.append('\0');
       
   717     commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
       
   718     appendString(&ba, commandLineBa, TargetByteOrder);
       
   719     return ba;
   856     return ba;
   720 }
   857 }
   721 
   858 
   722 void Launcher::startInferiorIfNeeded()
   859 void Launcher::startInferiorIfNeeded()
   723 {
   860 {
   735     QByteArray ba;
   872     QByteArray ba;
   736     appendInt(&ba, pid, BigEndian);
   873     appendInt(&ba, pid, BigEndian);
   737     appendInt(&ba, tid, BigEndian);
   874     appendInt(&ba, tid, BigEndian);
   738     d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
   875     d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
   739 }
   876 }
       
   877 
       
   878 // Acquire a device from SymbianDeviceManager, return 0 if not available.
       
   879 Launcher *Launcher::acquireFromDeviceManager(const QString &serverName,
       
   880                                              QObject *parent,
       
   881                                              QString *errorMessage)
       
   882 {
       
   883     SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
       
   884     const QSharedPointer<trk::TrkDevice> device = sdm->acquireDevice(serverName);
       
   885     if (device.isNull()) {
       
   886         *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName);
       
   887         return 0;
       
   888     }
       
   889     // Wire release signal.
       
   890     Launcher *rc = new Launcher(trk::Launcher::ActionPingOnly, device, parent);
       
   891     connect(rc, SIGNAL(deviceDescriptionReceived(QString,QString)),
       
   892             sdm, SLOT(setAdditionalInformation(QString,QString)));
       
   893     connect(rc, SIGNAL(destroyed(QString)), sdm, SLOT(releaseDevice(QString)));
       
   894     return rc;
       
   895 }
       
   896 
       
   897 // Preliminary release of device, disconnecting the signal.
       
   898 void Launcher::releaseToDeviceManager(Launcher *launcher)
       
   899 {
       
   900     SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
       
   901     // Disentangle launcher and its device, remove connection from destroyed
       
   902     launcher->setCloseDevice(false);
       
   903     TrkDevice *device = launcher->trkDevice().data();
       
   904     launcher->disconnect(device);
       
   905     device->disconnect(launcher);
       
   906     launcher->disconnect(sdm);
       
   907     sdm->releaseDevice(launcher->trkServerName());
       
   908 }
       
   909 
   740 } // namespace trk
   910 } // namespace trk