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; |
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 |
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 |
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; |
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); |
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 |