123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- //
- // Created by Tobias Hieta on 28/08/15.
- //
- #include "HelperLauncher.h"
- #include "QsLog.h"
- #include "settings/SettingsComponent.h"
- #include "settings/SettingsSection.h"
- #include "utils/Utils.h"
- #include "Names.h"
- #include <QTimer>
- /////////////////////////////////////////////////////////////////////////////////////////
- HelperLauncher::HelperLauncher(QObject* parent) : QObject(parent)
- {
- start();
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::start()
- {
- m_jsonClient = new LocalJsonClient("pmpHelper");
- connect(m_jsonClient, &QLocalSocket::connected, this, &HelperLauncher::didConnect);
- connect(m_jsonClient, static_cast<void (QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error), this, &HelperLauncher::socketError);
- connect(m_jsonClient, &LocalJsonClient::messageReceived, this, &HelperLauncher::gotMessage);
- connect(m_jsonClient, &QLocalSocket::disconnected, this, &HelperLauncher::socketDisconnect);
- #ifdef Q_OS_MAC
- m_launchd = new HelperLaunchd(this);
- #endif
- m_helperProcess = new QProcess(this);
- connect(SettingsComponent::Get().getSection(SETTINGS_SECTION_WEBCLIENT), &SettingsSection::valuesUpdated, [=](const QVariantMap& values)
- {
- if (values.contains("clientID"))
- updateClientId();
- });
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- bool HelperLauncher::connectToHelper()
- {
- if (m_jsonClient->state() == QLocalSocket::ConnectedState ||
- m_jsonClient->state() == QLocalSocket::ConnectingState)
- return true;
- QLOG_DEBUG() << "Connecting to helper";
- m_jsonClient->connectToServer();
- return true;
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- bool HelperLauncher::killHelper()
- {
- QVariantMap msg;
- msg.insert("command", "quit");
- m_jsonClient->sendMessage(msg);
- if (m_jsonClient->waitForBytesWritten(1000))
- {
- QLOG_DEBUG() << "Waiting for helper to die";
- if (!m_jsonClient->waitForDisconnected(3000))
- {
- QLOG_ERROR() << "Helper refused to disconnect. Didn't it get the PM?";
- return false;
- }
- QLOG_DEBUG() << "Helper gone";
- return true;
- }
- return false;
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::gotMessage(const QVariantMap& message)
- {
- if (message.value("version").toString() != Version::GetVersionString() ||
- message.value("path").toString() != HelperPath())
- {
- QLOG_WARN() << "Running helper does not match our current version. Killing it and starting a new one.";
- killHelper();
- }
- else
- {
- QLOG_DEBUG() << "Helper is running version:" << message.value("version").toString();
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::socketError(QLocalSocket::LocalSocketError error)
- {
- QLOG_DEBUG() << "Failed to connect to helper:" << m_jsonClient->errorString();
- if (error == QLocalSocket::ConnectionRefusedError ||
- error == QLocalSocket::ServerNotFoundError)
- launch();
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::socketDisconnect()
- {
- QLOG_DEBUG() << "Disconnected from helper, trying to relaunch";
- connectToHelper();
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::updateClientId()
- {
- // update clientId if we have it
- if (!SettingsComponent::Get().value(SETTINGS_SECTION_WEBCLIENT, "clientID").toString().isEmpty())
- {
- QVariantMap msg;
- msg.insert("command", "info");
- QVariantMap arg;
- arg.insert("clientId", SettingsComponent::Get().value(SETTINGS_SECTION_WEBCLIENT, "clientID").toString());
- QString userId = Utils::CurrentUserId();
- if (!userId.isEmpty())
- arg.insert("userId", userId);
- msg.insert("argument", arg);
- m_jsonClient->sendMessage(msg);
- }
- };
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::didConnect()
- {
- QLOG_DEBUG() << "Connected to helper";
- updateClientId();
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::launch()
- {
- QLOG_DEBUG() << "Launching helper:" << HelperPath();
- #ifdef Q_OS_MAC
- m_launchd->start();
- #else
- if (!m_helperProcess->startDetached(HelperPath(), QStringList()))
- {
- QLOG_ERROR() << "Failed to open helper: " + m_helperProcess->errorString();
- throw FatalException("Failed to launch helper: " + m_helperProcess->errorString());
- }
- #endif
- QTimer::singleShot(1000, this, &HelperLauncher::connectToHelper);
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- QString HelperLauncher::HelperPath()
- {
- QString programName = Names::HelperName();
- #ifdef Q_OS_WIN
- programName += ".exe";
- #endif
- QString helperPath = SettingsComponent::Get().value(SETTINGS_SECTION_PATH, "helperprogram").toString();
- // fallback to the resource dir
- if (helperPath.isEmpty() || !QFile().exists(helperPath))
- helperPath = Paths::resourceDir(programName);
- if (!QFile().exists(helperPath))
- throw FatalException("Can't find helper program");
- return helperPath;
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- void HelperLauncher::stop()
- {
- // this method needs to disconnect all signals from the helper as well, so it doesn't start up again.
- m_jsonClient->disconnect();
- killHelper();
- }
|