mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 20:56:51 +00:00
Other: fix bug in login screen <-> main window transition. [skip ci]
Other: fixed bug with split mode toggle. [skip ci] Other: fix QML warnings. [skip ci] Other: fix showMainWindow gRPC event binding. [skip ci]. QML Fixes [skip ci] Other: wait for EventStreamReader thread to finish on exit. Other: made BridgeMonitor generic, as ProcessMonitor. [skip ci]
This commit is contained in:
@ -19,7 +19,6 @@
|
|||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "AppController.h"
|
#include "AppController.h"
|
||||||
#include "GRPCServerWorker.h"
|
#include "GRPCServerWorker.h"
|
||||||
#include <bridgepp/BridgeUtils.h>
|
|
||||||
#include <bridgepp/Exception/Exception.h>
|
#include <bridgepp/Exception/Exception.h>
|
||||||
#include <bridgepp/Worker/Overseer.h>
|
#include <bridgepp/Worker/Overseer.h>
|
||||||
|
|
||||||
@ -58,35 +57,30 @@ int main(int argc, char **argv)
|
|||||||
QApplication::setOrganizationDomain("proton.ch");
|
QApplication::setOrganizationDomain("proton.ch");
|
||||||
QApplication::setQuitOnLastWindowClosed(true);
|
QApplication::setQuitOnLastWindowClosed(true);
|
||||||
|
|
||||||
app().log().setEchoInConsole(true);
|
Log& log = app().log();
|
||||||
app().log().info(QString("%1 started.").arg(applicationName));
|
log.setEchoInConsole(true);
|
||||||
|
log.info(QString("%1 started.").arg(applicationName));
|
||||||
|
|
||||||
MainWindow window(nullptr);
|
MainWindow window(nullptr);
|
||||||
app().setMainWindow(&window);
|
app().setMainWindow(&window);
|
||||||
window.setWindowTitle(QApplication::applicationName());
|
window.setWindowTitle(QApplication::applicationName());
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
GRPCServerWorker *serverWorker = new GRPCServerWorker(nullptr);
|
auto *serverWorker = new GRPCServerWorker(nullptr);
|
||||||
QObject::connect(serverWorker, &Worker::started, []() { app().log().info("Server worker started."); });
|
QObject::connect(serverWorker, &Worker::started, []() { app().log().info("Server worker started."); });
|
||||||
QObject::connect(serverWorker, &Worker::finished, []() { app().log().info("Server worker finished."); });
|
QObject::connect(serverWorker, &Worker::finished, []() { app().log().info("Server worker finished."); });
|
||||||
QObject::connect(serverWorker, &Worker::error, [](QString const &message) {
|
QObject::connect(serverWorker, &Worker::error, [&](QString const &message) { app().log().error(message); qApp->exit(EXIT_FAILURE); });
|
||||||
throw Exception(QString("gRPC Server encountered an error: %1").arg(message));
|
|
||||||
});
|
|
||||||
UPOverseer overseer = std::make_unique<Overseer>(serverWorker, nullptr);
|
UPOverseer overseer = std::make_unique<Overseer>(serverWorker, nullptr);
|
||||||
overseer->startWorker(true);
|
overseer->startWorker(true);
|
||||||
|
|
||||||
qint32 const exitCode = QApplication::exec();
|
qint32 const exitCode = QApplication::exec();
|
||||||
|
|
||||||
serverWorker->stop();
|
serverWorker->stop();
|
||||||
while (!overseer->isFinished())
|
if (!overseer->wait(5000))
|
||||||
{
|
log.warn("gRPC server took too long to finish.");
|
||||||
QThread::msleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
app().log().info(QString("%1 exiting with code %2.").arg(applicationName).arg(exitCode));
|
app().log().info(QString("%1 exiting with code %2.").arg(applicationName).arg(exitCode));
|
||||||
|
|
||||||
return exitCode;
|
return exitCode;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception const &e)
|
catch (Exception const &e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
#include "AppController.h"
|
#include "AppController.h"
|
||||||
#include "QMLBackend.h"
|
#include "QMLBackend.h"
|
||||||
#include "BridgeMonitor.h"
|
|
||||||
#include <bridgepp/GRPC/GRPCClient.h>
|
#include <bridgepp/GRPC/GRPCClient.h>
|
||||||
#include <bridgepp/Exception/Exception.h>
|
#include <bridgepp/Exception/Exception.h>
|
||||||
|
#include <bridgepp/ProcessMonitor.h>
|
||||||
#include <bridgepp/Log/Log.h>
|
#include <bridgepp/Log/Log.h>
|
||||||
|
|
||||||
|
|
||||||
@ -51,14 +51,14 @@ AppController::AppController()
|
|||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// \return The bridge worker, which can be null if the application was run in 'attach' mode (-a command-line switch).
|
/// \return The bridge worker, which can be null if the application was run in 'attach' mode (-a command-line switch).
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
BridgeMonitor *AppController::bridgeMonitor() const
|
ProcessMonitor *AppController::bridgeMonitor() const
|
||||||
{
|
{
|
||||||
if (!bridgeOverseer_)
|
if (!bridgeOverseer_)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// null bridgeOverseer is OK, it means we run in 'attached' mode (app attached to an already runnning instance of Bridge).
|
// null bridgeOverseer is OK, it means we run in 'attached' mode (app attached to an already runnning instance of Bridge).
|
||||||
// but if bridgeOverseer is not null, its attached worker must be a valid BridgeMonitor instance.
|
// but if bridgeOverseer is not null, its attached worker must be a valid ProcessMonitor instance.
|
||||||
auto *monitor = dynamic_cast<BridgeMonitor*>(bridgeOverseer_->worker());
|
auto *monitor = dynamic_cast<ProcessMonitor*>(bridgeOverseer_->worker());
|
||||||
if (!monitor)
|
if (!monitor)
|
||||||
throw Exception("Could not retrieve bridge monitor");
|
throw Exception("Could not retrieve bridge monitor");
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
|
|
||||||
class QMLBackend;
|
class QMLBackend;
|
||||||
class BridgeMonitor;
|
|
||||||
|
|
||||||
|
|
||||||
namespace bridgepp
|
namespace bridgepp
|
||||||
@ -29,6 +28,7 @@ namespace bridgepp
|
|||||||
class Log;
|
class Log;
|
||||||
class Overseer;
|
class Overseer;
|
||||||
class GRPCClient;
|
class GRPCClient;
|
||||||
|
class ProcessMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ public: // member functions.
|
|||||||
bridgepp::GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
|
bridgepp::GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
|
||||||
bridgepp::Log& log() { return *log_; } ///< Return a reference to the log.
|
bridgepp::Log& log() { return *log_; } ///< Return a reference to the log.
|
||||||
std::unique_ptr<bridgepp::Overseer>& bridgeOverseer() { return bridgeOverseer_; }; ///< Returns a reference the bridge overseer
|
std::unique_ptr<bridgepp::Overseer>& bridgeOverseer() { return bridgeOverseer_; }; ///< Returns a reference the bridge overseer
|
||||||
BridgeMonitor* bridgeMonitor() const; ///< Return the bridge worker.
|
bridgepp::ProcessMonitor* bridgeMonitor() const; ///< Return the bridge worker.
|
||||||
|
|
||||||
private: // member functions
|
private: // member functions
|
||||||
AppController(); ///< Default constructor.
|
AppController(); ///< Default constructor.
|
||||||
|
|||||||
@ -82,7 +82,6 @@ endif()
|
|||||||
add_executable(bridge-gui
|
add_executable(bridge-gui
|
||||||
Resources.qrc
|
Resources.qrc
|
||||||
AppController.cpp AppController.h
|
AppController.cpp AppController.h
|
||||||
BridgeMonitor.cpp BridgeMonitor.h
|
|
||||||
EventStreamWorker.cpp EventStreamWorker.h
|
EventStreamWorker.cpp EventStreamWorker.h
|
||||||
main.cpp
|
main.cpp
|
||||||
Pch.h
|
Pch.h
|
||||||
|
|||||||
@ -31,8 +31,8 @@ using namespace bridgepp;
|
|||||||
EventStreamReader::EventStreamReader(QObject *parent)
|
EventStreamReader::EventStreamReader(QObject *parent)
|
||||||
: Worker(parent)
|
: Worker(parent)
|
||||||
{
|
{
|
||||||
connect(this, &EventStreamReader::started, [&]() { app().log().debug("EventStreamReader started");});
|
connect(this, &EventStreamReader::started, [&]() { app().log().debug("EventStreamReader started"); });
|
||||||
connect(this, &EventStreamReader::finished, [&]() { app().log().debug("EventStreamReader finished");});
|
connect(this, &EventStreamReader::finished, [&]() { app().log().debug("EventStreamReader finished"); });
|
||||||
connect(this, &EventStreamReader::error, &app().log(), &Log::error);
|
connect(this, &EventStreamReader::error, &app().log(), &Log::error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,18 @@ void QMLBackend::init()
|
|||||||
this->retrieveUserList();
|
this->retrieveUserList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
/// \param timeoutMs The timeout after which the function should return false if the event stream reader is not finished. if -1 one, the function
|
||||||
|
/// never times out.
|
||||||
|
/// \return false if and only if the timeout delay was reached.
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
bool QMLBackend::waitForEventStreamReaderToFinish(qint32 timeoutMs)
|
||||||
|
{
|
||||||
|
return eventStreamOverseer_->wait(timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
//
|
//
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
@ -87,6 +99,7 @@ void QMLBackend::connectGrpcEvents()
|
|||||||
connect(client, &GRPCClient::reportBugFinished, this, &QMLBackend::reportBugFinished);
|
connect(client, &GRPCClient::reportBugFinished, this, &QMLBackend::reportBugFinished);
|
||||||
connect(client, &GRPCClient::reportBugSuccess, this, &QMLBackend::bugReportSendSuccess);
|
connect(client, &GRPCClient::reportBugSuccess, this, &QMLBackend::bugReportSendSuccess);
|
||||||
connect(client, &GRPCClient::reportBugError, this, &QMLBackend::bugReportSendError);
|
connect(client, &GRPCClient::reportBugError, this, &QMLBackend::bugReportSendError);
|
||||||
|
connect(client, &GRPCClient::showMainWindow, this, &QMLBackend::showMainWindow);
|
||||||
|
|
||||||
// cache events
|
// cache events
|
||||||
connect(client, &GRPCClient::isCacheOnDiskEnabledChanged, this, &QMLBackend::isDiskCacheEnabledChanged);
|
connect(client, &GRPCClient::isCacheOnDiskEnabledChanged, this, &QMLBackend::isDiskCacheEnabledChanged);
|
||||||
@ -168,15 +181,6 @@ void QMLBackend::retrieveUserList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
|
||||||
//
|
|
||||||
//****************************************************************************************************************************************************
|
|
||||||
void QMLBackend::clearUserList()
|
|
||||||
{
|
|
||||||
users_->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
//
|
//
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
@ -348,4 +352,4 @@ void QMLBackend::onResetFinished()
|
|||||||
{
|
{
|
||||||
emit resetFinished();
|
emit resetFinished();
|
||||||
this->restart();
|
this->restart();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public: // member functions.
|
|||||||
QMLBackend &operator=(QMLBackend const &) = delete; ///< Disabled assignment operator.
|
QMLBackend &operator=(QMLBackend const &) = delete; ///< Disabled assignment operator.
|
||||||
QMLBackend &operator=(QMLBackend &&) = delete; ///< Disabled move assignment operator.
|
QMLBackend &operator=(QMLBackend &&) = delete; ///< Disabled move assignment operator.
|
||||||
void init(); ///< Initialize the backend.
|
void init(); ///< Initialize the backend.
|
||||||
void clearUserList(); ///< Clear the user list.
|
bool waitForEventStreamReaderToFinish(qint32 timeoutMs); ///< Wait for the event stream reader to finish.
|
||||||
|
|
||||||
// invokable methods can be called from QML. They generally return a value, which slots cannot do.
|
// invokable methods can be called from QML. They generally return a value, which slots cannot do.
|
||||||
Q_INVOKABLE static QPoint getCursorPos(); // _ func() *core.QPoint `slot:"getCursorPos"`
|
Q_INVOKABLE static QPoint getCursorPos(); // _ func() *core.QPoint `slot:"getCursorPos"`
|
||||||
|
|||||||
@ -91,6 +91,7 @@ void UserList::reset()
|
|||||||
this->beginResetModel();
|
this->beginResetModel();
|
||||||
users_.clear();
|
users_.clear();
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
|
emit countChanged(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -102,6 +103,7 @@ void UserList::reset(QList<SPUser> const &users)
|
|||||||
this->beginResetModel();
|
this->beginResetModel();
|
||||||
users_ = users;
|
users_ = users;
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
|
emit countChanged(users_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -114,6 +116,7 @@ void UserList::appendUser(SPUser const &user)
|
|||||||
this->beginInsertRows(QModelIndex(), size, size);
|
this->beginInsertRows(QModelIndex(), size, size);
|
||||||
users_.append(user);
|
users_.append(user);
|
||||||
this->endInsertRows();
|
this->endInsertRows();
|
||||||
|
emit countChanged(users_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -127,6 +130,7 @@ void UserList::removeUserAt(int row)
|
|||||||
this->beginRemoveRows(QModelIndex(), row, row);
|
this->beginRemoveRows(QModelIndex(), row, row);
|
||||||
users_.removeAt(row);
|
users_.removeAt(row);
|
||||||
this->endRemoveRows();
|
this->endRemoveRows();
|
||||||
|
emit countChanged(users_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,6 @@
|
|||||||
#ifndef BRIDGE_GUI_VERSION_H
|
#ifndef BRIDGE_GUI_VERSION_H
|
||||||
#define BRIDGE_GUI_VERSION_H
|
#define BRIDGE_GUI_VERSION_H
|
||||||
|
|
||||||
#define PROJECT_VER "2.2.1+git"
|
#define PROJECT_VER "2.2.2+git"
|
||||||
|
|
||||||
#endif // BRIDGE_GUI_VERSION_H
|
#endif // BRIDGE_GUI_VERSION_H
|
||||||
|
|||||||
@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "QMLBackend.h"
|
#include "QMLBackend.h"
|
||||||
#include "BridgeMonitor.h"
|
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
#include <bridgepp/Log/Log.h>
|
#include <bridgepp/Log/Log.h>
|
||||||
#include <bridgepp/BridgeUtils.h>
|
#include <bridgepp/BridgeUtils.h>
|
||||||
#include <bridgepp/Exception/Exception.h>
|
#include <bridgepp/Exception/Exception.h>
|
||||||
|
#include <bridgepp/ProcessMonitor.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace bridgepp;
|
using namespace bridgepp;
|
||||||
@ -29,11 +29,30 @@ using namespace bridgepp;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// \brief The file extension for the bridge executable file.
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
QString const exeSuffix = ".exe";
|
||||||
|
#else
|
||||||
|
QString const exeSuffix;
|
||||||
|
#endif
|
||||||
|
|
||||||
QString const launcherFlag = "--launcher"; ///< launcher flag parameter used for bridge.
|
QString const launcherFlag = "--launcher"; ///< launcher flag parameter used for bridge.
|
||||||
QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file.
|
QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file.
|
||||||
|
QString const exeName = "proton-bridge" + exeSuffix; ///< The bridge executable file name.*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
/// \return The path of the bridge executable.
|
||||||
|
/// \return A null string if the executable could not be located.
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
QString locateBridgeExe()
|
||||||
|
{
|
||||||
|
QFileInfo const fileInfo(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(exeName));
|
||||||
|
return (fileInfo.exists() && fileInfo.isFile() && fileInfo.isExecutable()) ? fileInfo.absoluteFilePath() : QString();
|
||||||
|
}
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// // initialize the Qt application.
|
/// // initialize the Qt application.
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
@ -93,7 +112,7 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
|
|||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// \param[in] lock The lock file to be checked.
|
/// \param[in] lock The lock file to be checked.
|
||||||
/// \return True if the lock can be taken, false otherwize.
|
/// \return True if the lock can be taken, false otherwise.
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
bool checkSingleInstance(QLockFile &lock)
|
bool checkSingleInstance(QLockFile &lock)
|
||||||
{
|
{
|
||||||
@ -168,14 +187,14 @@ void launchBridge(QStringList const &args)
|
|||||||
UPOverseer& overseer = app().bridgeOverseer();
|
UPOverseer& overseer = app().bridgeOverseer();
|
||||||
overseer.reset();
|
overseer.reset();
|
||||||
|
|
||||||
const QString bridgeExePath = BridgeMonitor::locateBridgeExe();
|
const QString bridgeExePath = locateBridgeExe();
|
||||||
|
|
||||||
if (bridgeExePath.isEmpty())
|
if (bridgeExePath.isEmpty())
|
||||||
throw Exception("Could not locate the bridge executable path");
|
throw Exception("Could not locate the bridge executable path");
|
||||||
else
|
else
|
||||||
app().log().debug(QString("Bridge executable path: %1").arg(QDir::toNativeSeparators(bridgeExePath)));
|
app().log().debug(QString("Bridge executable path: %1").arg(QDir::toNativeSeparators(bridgeExePath)));
|
||||||
|
|
||||||
overseer = std::make_unique<Overseer>(new BridgeMonitor(bridgeExePath, args, nullptr), nullptr);
|
overseer = std::make_unique<Overseer>(new ProcessMonitor(bridgeExePath, args, nullptr), nullptr);
|
||||||
overseer->startWorker(true);
|
overseer->startWorker(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,16 +253,16 @@ int main(int argc, char *argv[])
|
|||||||
if (!rootObject)
|
if (!rootObject)
|
||||||
throw Exception("Could not create root object.");
|
throw Exception("Could not create root object.");
|
||||||
|
|
||||||
BridgeMonitor *bridgeMonitor = app().bridgeMonitor();
|
ProcessMonitor *bridgeMonitor = app().bridgeMonitor();
|
||||||
bool bridgeExited = false;
|
bool bridgeExited = false;
|
||||||
bool startError = false;
|
bool startError = false;
|
||||||
QMetaObject::Connection connection;
|
QMetaObject::Connection connection;
|
||||||
if (bridgeMonitor)
|
if (bridgeMonitor)
|
||||||
{
|
{
|
||||||
const BridgeMonitor::MonitorStatus& status = bridgeMonitor->getStatus();
|
const ProcessMonitor::MonitorStatus& status = bridgeMonitor->getStatus();
|
||||||
if (!status.running && !attach)
|
if (!status.running && !attach)
|
||||||
{
|
{
|
||||||
// BridgeMonitor already stopped meaning we are attached to an orphan Bridge.
|
// ProcessMonitor already stopped meaning we are attached to an orphan Bridge.
|
||||||
// Restart the full process to be sure there is no more bridge orphans
|
// Restart the full process to be sure there is no more bridge orphans
|
||||||
app().log().error("Found orphan bridge, need to restart.");
|
app().log().error("Found orphan bridge, need to restart.");
|
||||||
app().backend().forceLauncher(launcher);
|
app().backend().forceLauncher(launcher);
|
||||||
@ -254,7 +273,7 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
app().log().debug(QString("Monitoring Bridge PID : %1").arg(status.pid));
|
app().log().debug(QString("Monitoring Bridge PID : %1").arg(status.pid));
|
||||||
connection = QObject::connect(bridgeMonitor, &BridgeMonitor::processExited, [&](int returnCode) {
|
connection = QObject::connect(bridgeMonitor, &ProcessMonitor::processExited, [&](int returnCode) {
|
||||||
bridgeExited = true;// clazy:exclude=lambda-in-connect
|
bridgeExited = true;// clazy:exclude=lambda-in-connect
|
||||||
qGuiApp->exit(returnCode);
|
qGuiApp->exit(returnCode);
|
||||||
});
|
});
|
||||||
@ -267,6 +286,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QObject::disconnect(connection);
|
QObject::disconnect(connection);
|
||||||
app().grpc().stopEventStream();
|
app().grpc().stopEventStream();
|
||||||
|
if (!app().backend().waitForEventStreamReaderToFinish(5000))
|
||||||
|
log.warn("Event stream reader took too long to finish.");
|
||||||
|
|
||||||
// We manually delete the QML components to avoid warnings error due to order of deletion of C++ / JS objects and singletons.
|
// We manually delete the QML components to avoid warnings error due to order of deletion of C++ / JS objects and singletons.
|
||||||
rootObject.reset();
|
rootObject.reset();
|
||||||
@ -280,7 +301,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
catch (Exception const &e)
|
catch (Exception const &e)
|
||||||
{
|
{
|
||||||
app().log().error(e.qwhat());
|
QTextStream(stderr) << e.qwhat() << "\n";
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -258,7 +258,7 @@ Item {
|
|||||||
signIn.username = this.user.username
|
signIn.username = this.user.username
|
||||||
rightContent.showSignIn()
|
rightContent.showSignIn()
|
||||||
}
|
}
|
||||||
onShowSetupGuide: {
|
onShowSetupGuide: function(user, address) {
|
||||||
root.showSetupGuide(user,address)
|
root.showSetupGuide(user,address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,6 @@ SettingsView {
|
|||||||
type: Label.Body
|
type: Label.Body
|
||||||
color: root.colorScheme.text_weak
|
color: root.colorScheme.text_weak
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.maximumWidth: this.parent.Layout.maximumWidth
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ ApplicationWindow {
|
|||||||
target: Backend.users
|
target: Backend.users
|
||||||
|
|
||||||
function onRowsInserted(parent, first, last) {
|
function onRowsInserted(parent, first, last) {
|
||||||
// considerring that users are added one-by-one
|
// considering that users are added one-by-one
|
||||||
var user = Backend.users.get(first)
|
var user = Backend.users.get(first)
|
||||||
|
|
||||||
if (!user.loggedIn) {
|
if (!user.loggedIn) {
|
||||||
@ -130,7 +130,7 @@ ApplicationWindow {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
onShowSetupGuide: {
|
onShowSetupGuide: function(user, address) {
|
||||||
root.showSetup(user,address)
|
root.showSetup(user,address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,6 @@ SettingsView {
|
|||||||
type: Label.Body
|
type: Label.Body
|
||||||
color: root.colorScheme.text_weak
|
color: root.colorScheme.text_weak
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.maximumWidth: this.parent.Layout.maximumWidth
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -108,6 +108,7 @@ add_library(bridgepp
|
|||||||
bridgepp/GRPC/GRPCUtils.cpp bridgepp/GRPC/GRPCUtils.h
|
bridgepp/GRPC/GRPCUtils.cpp bridgepp/GRPC/GRPCUtils.h
|
||||||
${PROTO_CPP_FILE} ${PROTO_H_FILE} ${GRPC_CPP_FILE} ${GRPC_H_FILE}
|
${PROTO_CPP_FILE} ${PROTO_H_FILE} ${GRPC_CPP_FILE} ${GRPC_H_FILE}
|
||||||
bridgepp/Log/Log.h bridgepp/Log/Log.cpp
|
bridgepp/Log/Log.h bridgepp/Log/Log.cpp
|
||||||
|
bridgepp/ProcessMonitor.cpp bridgepp/ProcessMonitor.h
|
||||||
bridgepp/User/User.cpp bridgepp/User/User.h
|
bridgepp/User/User.cpp bridgepp/User/User.h
|
||||||
bridgepp/Worker/Worker.h bridgepp/Worker/Overseer.h bridgepp/Worker/Overseer.cpp
|
bridgepp/Worker/Worker.h bridgepp/Worker/Overseer.h bridgepp/Worker/Overseer.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@ -16,14 +16,15 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#ifndef BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
|
#ifndef BRIDGE_PP_TESTER_BRIDGE_UTILS_H
|
||||||
#define BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
|
#define BRIDGE_PP_TESTER_BRIDGE_UTILS_H
|
||||||
|
|
||||||
|
|
||||||
#include <bridgepp/User/User.h>
|
#include <bridgepp/User/User.h>
|
||||||
|
|
||||||
|
|
||||||
namespace bridgepp {
|
namespace bridgepp
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
QString userConfigDir(); ///< Get the path of the user configuration folder.
|
QString userConfigDir(); ///< Get the path of the user configuration folder.
|
||||||
@ -34,8 +35,8 @@ QString randomFirstName(); ///< Get a random first name from a pre-determined li
|
|||||||
QString randomLastName(); ///< Get a random first name from a pre-determined list.
|
QString randomLastName(); ///< Get a random first name from a pre-determined list.
|
||||||
SPUser randomUser(); ///< Get a random user.
|
SPUser randomUser(); ///< Get a random user.
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BRIDGE_PP_TESTER_BRIDGE_UTILS_H
|
||||||
#endif // BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
|
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#ifndef BRIDGE_GUI_TESTER_EVENT_FACTORY_H
|
#ifndef BRIDGE_PP_EVENT_FACTORY_H
|
||||||
#define BRIDGE_GUI_TESTER_EVENT_FACTORY_H
|
#define BRIDGE_PP_EVENT_FACTORY_H
|
||||||
|
|
||||||
|
|
||||||
#include "bridge.grpc.pb.h"
|
#include "bridge.grpc.pb.h"
|
||||||
@ -85,4 +85,4 @@ SPStreamEvent newUserChangedEvent(QString const &userID); ///< Create a new User
|
|||||||
} // namespace bridgepp
|
} // namespace bridgepp
|
||||||
|
|
||||||
|
|
||||||
#endif //BRIDGE_GUI_TESTER_EVENT_FACTORY_H
|
#endif //BRIDGE_PP_EVENT_FACTORY_H
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#ifndef BRIDGE_GUI_RPC_CLIENT_H
|
#ifndef BRIDGE_PP_RPC_CLIENT_H
|
||||||
#define BRIDGE_GUI_RPC_CLIENT_H
|
#define BRIDGE_PP_RPC_CLIENT_H
|
||||||
|
|
||||||
|
|
||||||
#include "../User/User.h"
|
#include "../User/User.h"
|
||||||
@ -233,4 +233,4 @@ private: // data members.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // BRIDGE_GUI_RPC_CLIENT_H
|
#endif // BRIDGE_PP_RPC_CLIENT_H
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#ifndef BRIDGE_GUI_GRPC_UTILS_H
|
#ifndef BRIDGE_PP_GRPC_UTILS_H
|
||||||
#define BRIDGE_GUI_GRPC_UTILS_H
|
#define BRIDGE_PP_GRPC_UTILS_H
|
||||||
|
|
||||||
|
|
||||||
#include "../User/User.h"
|
#include "../User/User.h"
|
||||||
@ -42,4 +42,4 @@ SPUser userFromGRPC(grpc::User const &grpcUser); ///< Create a bridgepp::User fr
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // BRIDGE_GUI_GRPC_UTILS_H
|
#endif // BRIDGE_PP_GRPC_UTILS_H
|
||||||
|
|||||||
@ -16,62 +16,35 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#include "BridgeMonitor.h"
|
#include "ProcessMonitor.h"
|
||||||
#include <bridgepp/Exception/Exception.h>
|
#include "Exception/Exception.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace bridgepp;
|
namespace bridgepp
|
||||||
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/// \brief The file extension for the bridge executable file.
|
|
||||||
#ifdef Q_OS_WIN32
|
|
||||||
QString const exeSuffix = ".exe";
|
|
||||||
#else
|
|
||||||
QString const exeSuffix;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString const exeName = "proton-bridge" + exeSuffix; ///< The bridge executable file name.*
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// \return The path of the bridge executable.
|
/// \param[in] exePath The path of the executable.
|
||||||
/// \return A null string if the executable could not be located.
|
|
||||||
//****************************************************************************************************************************************************
|
|
||||||
QString BridgeMonitor::locateBridgeExe()
|
|
||||||
{
|
|
||||||
QFileInfo const fileInfo(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(exeName));
|
|
||||||
return (fileInfo.exists() && fileInfo.isFile() && fileInfo.isExecutable()) ? fileInfo.absoluteFilePath() : QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
|
||||||
/// \param[in] exePath The path of the Bridge executable.
|
|
||||||
/// \param[in] parent The parent object of the worker.
|
/// \param[in] parent The parent object of the worker.
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
BridgeMonitor::BridgeMonitor(QString const &exePath, QStringList const &args, QObject *parent)
|
ProcessMonitor::ProcessMonitor(QString const &exePath, QStringList const &args, QObject *parent)
|
||||||
: Worker(parent)
|
: Worker(parent)
|
||||||
, exePath_(exePath)
|
, exePath_(exePath)
|
||||||
, args_(args)
|
, args_(args)
|
||||||
{
|
{
|
||||||
QFileInfo fileInfo(exePath);
|
QFileInfo fileInfo(exePath);
|
||||||
if (!fileInfo.exists())
|
if (!fileInfo.exists())
|
||||||
throw Exception("Could not locate Bridge executable.");
|
throw Exception(QString("Could not locate %1 executable.").arg(fileInfo.baseName()));
|
||||||
if ((!fileInfo.isFile()) || (!fileInfo.isExecutable()))
|
if ((!fileInfo.isFile()) || (!fileInfo.isExecutable()))
|
||||||
throw Exception("Invalid bridge executable");
|
throw Exception(QString("Invalid %1 executable").arg(fileInfo.baseName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
//
|
//
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
void BridgeMonitor::run()
|
void ProcessMonitor::run()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -92,9 +65,9 @@ void BridgeMonitor::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_.running = false;
|
status_.running = false;
|
||||||
status_.returnCode = p.exitCode();
|
status_.returnCode = p.exitCode();
|
||||||
|
|
||||||
emit processExited(status_.returnCode );
|
emit processExited(status_.returnCode);
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
catch (Exception const &e)
|
catch (Exception const &e)
|
||||||
@ -103,10 +76,14 @@ void BridgeMonitor::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// \return status of the monitored process
|
/// \return status of the monitored process
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
const BridgeMonitor::MonitorStatus& BridgeMonitor::getStatus()
|
const ProcessMonitor::MonitorStatus &ProcessMonitor::getStatus()
|
||||||
{
|
{
|
||||||
return status_;
|
return status_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace bridgepp
|
||||||
@ -16,48 +16,52 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BRIDGE_PP_PROCESS_MONITOR_H
|
||||||
#ifndef BRIDGE_GUI_BRIDGE_MONITOR_H
|
#define BRIDGE_PP_PROCESS_MONITOR_H
|
||||||
#define BRIDGE_GUI_BRIDGE_MONITOR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <bridgepp/Worker/Worker.h>
|
#include "Worker/Worker.h"
|
||||||
|
|
||||||
|
|
||||||
//**********************************************************************************************************************
|
namespace bridgepp
|
||||||
/// \brief Bridge process launcher and monitor class.
|
|
||||||
//**********************************************************************************************************************
|
|
||||||
class BridgeMonitor: public bridgepp::Worker
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public: // static member functions
|
|
||||||
static QString locateBridgeExe(); ///< Try to find the bridge executable path.
|
|
||||||
|
|
||||||
struct MonitorStatus {
|
|
||||||
|
//**********************************************************************************************************************
|
||||||
|
/// \brief Process launcher and monitor class.
|
||||||
|
//**********************************************************************************************************************
|
||||||
|
class ProcessMonitor : public Worker
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public: // static member functions
|
||||||
|
struct MonitorStatus
|
||||||
|
{
|
||||||
bool running = false;
|
bool running = false;
|
||||||
int returnCode = 0;
|
int returnCode = 0;
|
||||||
qint64 pid = 0;
|
qint64 pid = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
public: // member functions.
|
public: // member functions.
|
||||||
BridgeMonitor(QString const& exePath, QStringList const &args, QObject *parent); ///< Default constructor.
|
ProcessMonitor(QString const &exePath, QStringList const &args, QObject *parent); ///< Default constructor.
|
||||||
BridgeMonitor(BridgeMonitor const&) = delete; ///< Disabled copy-constructor.
|
ProcessMonitor(ProcessMonitor const &) = delete; ///< Disabled copy-constructor.
|
||||||
BridgeMonitor(BridgeMonitor&&) = delete; ///< Disabled assignment copy-constructor.
|
ProcessMonitor(ProcessMonitor &&) = delete; ///< Disabled assignment copy-constructor.
|
||||||
~BridgeMonitor() override = default; ///< Destructor.
|
~ProcessMonitor() override = default; ///< Destructor.
|
||||||
BridgeMonitor& operator=(BridgeMonitor const&) = delete; ///< Disabled assignment operator.
|
ProcessMonitor &operator=(ProcessMonitor const &) = delete; ///< Disabled assignment operator.
|
||||||
BridgeMonitor& operator=(BridgeMonitor&&) = delete; ///< Disabled move assignment operator.
|
ProcessMonitor &operator=(ProcessMonitor &&) = delete; ///< Disabled move assignment operator.
|
||||||
void run() override; ///< Run the worker.
|
void run() override; ///< Run the worker.
|
||||||
|
MonitorStatus const &getStatus();
|
||||||
|
|
||||||
const MonitorStatus& getStatus();
|
|
||||||
signals:
|
signals:
|
||||||
void processExited(int code); ///< Slot for the exiting of the process.
|
void processExited(int code); ///< Slot for the exiting of the process.
|
||||||
|
|
||||||
private: // data members
|
private: // data members
|
||||||
QString const exePath_; ///< The path to the bridge executable.
|
QString const exePath_; ///< The path to the executable.
|
||||||
QStringList args_; ///< arguments to be passed to the brigde.
|
QStringList args_; ///< arguments to be passed to the brigde.
|
||||||
MonitorStatus status_; ///< Status of the monitoring.
|
MonitorStatus status_; ///< Status of the monitoring.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BRIDGE_GUI_BRIDGE_MONITOR_H
|
|
||||||
|
#endif //BRIDGE_PP_PROCESS_MONITOR_H
|
||||||
@ -16,8 +16,8 @@
|
|||||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#ifndef BRIDGE_GUI_USER_H
|
#ifndef BRIDGE_PP_USER_H
|
||||||
#define BRIDGE_GUI_USER_H
|
#define BRIDGE_PP_USER_H
|
||||||
|
|
||||||
|
|
||||||
namespace bridgepp
|
namespace bridgepp
|
||||||
@ -127,4 +127,4 @@ private: // data members.
|
|||||||
} // namespace bridgepp
|
} // namespace bridgepp
|
||||||
|
|
||||||
|
|
||||||
#endif // BRIDGE_GUI_USER_H
|
#endif // BRIDGE_PP_USER_H
|
||||||
|
|||||||
@ -108,6 +108,26 @@ bool Overseer::isFinished() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
/// \param timeoutMs The timeout after which the function should return false if the event stream reader is not finished. if -1 one, the function
|
||||||
|
/// never times out.
|
||||||
|
/// \return false if and only if the timeout delay was reached.
|
||||||
|
//****************************************************************************************************************************************************
|
||||||
|
bool Overseer::wait(qint32 timeoutMs) const
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
while (!this->isFinished()) {
|
||||||
|
if ((timeoutMs >= 0) && (timer.elapsed() > timeoutMs))
|
||||||
|
return false;
|
||||||
|
QThread::msleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
/// \return The worker.
|
/// \return The worker.
|
||||||
//****************************************************************************************************************************************************
|
//****************************************************************************************************************************************************
|
||||||
|
|||||||
@ -41,6 +41,7 @@ public: // member functions.
|
|||||||
Overseer &operator=(Overseer const &) = delete; ///< Disabled assignment operator.
|
Overseer &operator=(Overseer const &) = delete; ///< Disabled assignment operator.
|
||||||
Overseer &operator=(Overseer &&) = delete; ///< Disabled move assignment operator.
|
Overseer &operator=(Overseer &&) = delete; ///< Disabled move assignment operator.
|
||||||
bool isFinished() const; ///< Check if the worker is finished.
|
bool isFinished() const; ///< Check if the worker is finished.
|
||||||
|
bool wait(qint32 timeoutMs) const; ///< Wait for the worker to finish.
|
||||||
Worker *worker() const; ///< Return worker.
|
Worker *worker() const; ///< Return worker.
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|||||||
@ -64,7 +64,7 @@ func grpcUserFromBridge(user types.User) *User {
|
|||||||
Username: user.Username(),
|
Username: user.Username(),
|
||||||
AvatarText: getInitials(user.Username()),
|
AvatarText: getInitials(user.Username()),
|
||||||
LoggedIn: user.IsConnected(),
|
LoggedIn: user.IsConnected(),
|
||||||
SplitMode: user.IsCombinedAddressMode(),
|
SplitMode: !user.IsCombinedAddressMode(),
|
||||||
SetupGuideSeen: true, // users listed have already seen the setup guide.
|
SetupGuideSeen: true, // users listed have already seen the setup guide.
|
||||||
UsedBytes: user.UsedBytes(),
|
UsedBytes: user.UsedBytes(),
|
||||||
TotalBytes: user.TotalBytes(),
|
TotalBytes: user.TotalBytes(),
|
||||||
|
|||||||
Reference in New Issue
Block a user