mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 12:46:46 +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 "AppController.h"
|
||||
#include "GRPCServerWorker.h"
|
||||
#include <bridgepp/BridgeUtils.h>
|
||||
#include <bridgepp/Exception/Exception.h>
|
||||
#include <bridgepp/Worker/Overseer.h>
|
||||
|
||||
@ -58,35 +57,30 @@ int main(int argc, char **argv)
|
||||
QApplication::setOrganizationDomain("proton.ch");
|
||||
QApplication::setQuitOnLastWindowClosed(true);
|
||||
|
||||
app().log().setEchoInConsole(true);
|
||||
app().log().info(QString("%1 started.").arg(applicationName));
|
||||
Log& log = app().log();
|
||||
log.setEchoInConsole(true);
|
||||
log.info(QString("%1 started.").arg(applicationName));
|
||||
|
||||
MainWindow window(nullptr);
|
||||
app().setMainWindow(&window);
|
||||
window.setWindowTitle(QApplication::applicationName());
|
||||
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::finished, []() { app().log().info("Server worker finished."); });
|
||||
QObject::connect(serverWorker, &Worker::error, [](QString const &message) {
|
||||
throw Exception(QString("gRPC Server encountered an error: %1").arg(message));
|
||||
});
|
||||
QObject::connect(serverWorker, &Worker::error, [&](QString const &message) { app().log().error(message); qApp->exit(EXIT_FAILURE); });
|
||||
UPOverseer overseer = std::make_unique<Overseer>(serverWorker, nullptr);
|
||||
overseer->startWorker(true);
|
||||
|
||||
qint32 const exitCode = QApplication::exec();
|
||||
|
||||
serverWorker->stop();
|
||||
while (!overseer->isFinished())
|
||||
{
|
||||
QThread::msleep(10);
|
||||
}
|
||||
if (!overseer->wait(5000))
|
||||
log.warn("gRPC server took too long to finish.");
|
||||
|
||||
app().log().info(QString("%1 exiting with code %2.").arg(applicationName).arg(exitCode));
|
||||
|
||||
return exitCode;
|
||||
|
||||
}
|
||||
catch (Exception const &e)
|
||||
{
|
||||
|
||||
@ -18,9 +18,9 @@
|
||||
|
||||
#include "AppController.h"
|
||||
#include "QMLBackend.h"
|
||||
#include "BridgeMonitor.h"
|
||||
#include <bridgepp/GRPC/GRPCClient.h>
|
||||
#include <bridgepp/Exception/Exception.h>
|
||||
#include <bridgepp/ProcessMonitor.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).
|
||||
//****************************************************************************************************************************************************
|
||||
BridgeMonitor *AppController::bridgeMonitor() const
|
||||
ProcessMonitor *AppController::bridgeMonitor() const
|
||||
{
|
||||
if (!bridgeOverseer_)
|
||||
return nullptr;
|
||||
|
||||
// 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.
|
||||
auto *monitor = dynamic_cast<BridgeMonitor*>(bridgeOverseer_->worker());
|
||||
// but if bridgeOverseer is not null, its attached worker must be a valid ProcessMonitor instance.
|
||||
auto *monitor = dynamic_cast<ProcessMonitor*>(bridgeOverseer_->worker());
|
||||
if (!monitor)
|
||||
throw Exception("Could not retrieve bridge monitor");
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
|
||||
|
||||
class QMLBackend;
|
||||
class BridgeMonitor;
|
||||
|
||||
|
||||
namespace bridgepp
|
||||
@ -29,6 +28,7 @@ namespace bridgepp
|
||||
class Log;
|
||||
class Overseer;
|
||||
class GRPCClient;
|
||||
class ProcessMonitor;
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ public: // member functions.
|
||||
bridgepp::GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
|
||||
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
|
||||
BridgeMonitor* bridgeMonitor() const; ///< Return the bridge worker.
|
||||
bridgepp::ProcessMonitor* bridgeMonitor() const; ///< Return the bridge worker.
|
||||
|
||||
private: // member functions
|
||||
AppController(); ///< Default constructor.
|
||||
|
||||
@ -82,7 +82,6 @@ endif()
|
||||
add_executable(bridge-gui
|
||||
Resources.qrc
|
||||
AppController.cpp AppController.h
|
||||
BridgeMonitor.cpp BridgeMonitor.h
|
||||
EventStreamWorker.cpp EventStreamWorker.h
|
||||
main.cpp
|
||||
Pch.h
|
||||
|
||||
@ -31,8 +31,8 @@ using namespace bridgepp;
|
||||
EventStreamReader::EventStreamReader(QObject *parent)
|
||||
: Worker(parent)
|
||||
{
|
||||
connect(this, &EventStreamReader::started, [&]() { app().log().debug("EventStreamReader started");});
|
||||
connect(this, &EventStreamReader::finished, [&]() { app().log().debug("EventStreamReader finished");});
|
||||
connect(this, &EventStreamReader::started, [&]() { app().log().debug("EventStreamReader started"); });
|
||||
connect(this, &EventStreamReader::finished, [&]() { app().log().debug("EventStreamReader finished"); });
|
||||
connect(this, &EventStreamReader::error, &app().log(), &Log::error);
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +73,18 @@ void QMLBackend::init()
|
||||
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::reportBugSuccess, this, &QMLBackend::bugReportSendSuccess);
|
||||
connect(client, &GRPCClient::reportBugError, this, &QMLBackend::bugReportSendError);
|
||||
connect(client, &GRPCClient::showMainWindow, this, &QMLBackend::showMainWindow);
|
||||
|
||||
// cache events
|
||||
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();
|
||||
this->restart();
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ public: // member functions.
|
||||
QMLBackend &operator=(QMLBackend const &) = delete; ///< Disabled assignment operator.
|
||||
QMLBackend &operator=(QMLBackend &&) = delete; ///< Disabled move assignment operator.
|
||||
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.
|
||||
Q_INVOKABLE static QPoint getCursorPos(); // _ func() *core.QPoint `slot:"getCursorPos"`
|
||||
|
||||
@ -91,6 +91,7 @@ void UserList::reset()
|
||||
this->beginResetModel();
|
||||
users_.clear();
|
||||
this->endResetModel();
|
||||
emit countChanged(0);
|
||||
}
|
||||
|
||||
|
||||
@ -102,6 +103,7 @@ void UserList::reset(QList<SPUser> const &users)
|
||||
this->beginResetModel();
|
||||
users_ = users;
|
||||
this->endResetModel();
|
||||
emit countChanged(users_.size());
|
||||
}
|
||||
|
||||
|
||||
@ -114,6 +116,7 @@ void UserList::appendUser(SPUser const &user)
|
||||
this->beginInsertRows(QModelIndex(), size, size);
|
||||
users_.append(user);
|
||||
this->endInsertRows();
|
||||
emit countChanged(users_.size());
|
||||
}
|
||||
|
||||
|
||||
@ -127,6 +130,7 @@ void UserList::removeUserAt(int row)
|
||||
this->beginRemoveRows(QModelIndex(), row, row);
|
||||
users_.removeAt(row);
|
||||
this->endRemoveRows();
|
||||
emit countChanged(users_.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -19,6 +19,6 @@
|
||||
#ifndef 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
|
||||
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
|
||||
#include "QMLBackend.h"
|
||||
#include "BridgeMonitor.h"
|
||||
#include "Version.h"
|
||||
#include <bridgepp/Log/Log.h>
|
||||
#include <bridgepp/BridgeUtils.h>
|
||||
#include <bridgepp/Exception/Exception.h>
|
||||
#include <bridgepp/ProcessMonitor.h>
|
||||
|
||||
|
||||
using namespace bridgepp;
|
||||
@ -29,11 +29,30 @@ using 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 launcherFlag = "--launcher"; ///< launcher flag parameter used for bridge.
|
||||
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.
|
||||
//****************************************************************************************************************************************************
|
||||
@ -93,7 +112,7 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \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)
|
||||
{
|
||||
@ -168,14 +187,14 @@ void launchBridge(QStringList const &args)
|
||||
UPOverseer& overseer = app().bridgeOverseer();
|
||||
overseer.reset();
|
||||
|
||||
const QString bridgeExePath = BridgeMonitor::locateBridgeExe();
|
||||
const QString bridgeExePath = locateBridgeExe();
|
||||
|
||||
if (bridgeExePath.isEmpty())
|
||||
throw Exception("Could not locate the bridge executable path");
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
||||
@ -234,16 +253,16 @@ int main(int argc, char *argv[])
|
||||
if (!rootObject)
|
||||
throw Exception("Could not create root object.");
|
||||
|
||||
BridgeMonitor *bridgeMonitor = app().bridgeMonitor();
|
||||
ProcessMonitor *bridgeMonitor = app().bridgeMonitor();
|
||||
bool bridgeExited = false;
|
||||
bool startError = false;
|
||||
QMetaObject::Connection connection;
|
||||
if (bridgeMonitor)
|
||||
{
|
||||
const BridgeMonitor::MonitorStatus& status = bridgeMonitor->getStatus();
|
||||
const ProcessMonitor::MonitorStatus& status = bridgeMonitor->getStatus();
|
||||
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
|
||||
app().log().error("Found orphan bridge, need to restart.");
|
||||
app().backend().forceLauncher(launcher);
|
||||
@ -254,7 +273,7 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
{
|
||||
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
|
||||
qGuiApp->exit(returnCode);
|
||||
});
|
||||
@ -267,6 +286,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
QObject::disconnect(connection);
|
||||
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.
|
||||
rootObject.reset();
|
||||
@ -280,7 +301,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
catch (Exception const &e)
|
||||
{
|
||||
app().log().error(e.qwhat());
|
||||
QTextStream(stderr) << e.qwhat() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +258,7 @@ Item {
|
||||
signIn.username = this.user.username
|
||||
rightContent.showSignIn()
|
||||
}
|
||||
onShowSetupGuide: {
|
||||
onShowSetupGuide: function(user, address) {
|
||||
root.showSetupGuide(user,address)
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,6 @@ SettingsView {
|
||||
type: Label.Body
|
||||
color: root.colorScheme.text_weak
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: this.parent.Layout.maximumWidth
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ ApplicationWindow {
|
||||
target: Backend.users
|
||||
|
||||
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)
|
||||
|
||||
if (!user.loggedIn) {
|
||||
@ -130,7 +130,7 @@ ApplicationWindow {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
onShowSetupGuide: {
|
||||
onShowSetupGuide: function(user, address) {
|
||||
root.showSetup(user,address)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,6 @@ SettingsView {
|
||||
type: Label.Body
|
||||
color: root.colorScheme.text_weak
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: this.parent.Layout.maximumWidth
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
|
||||
@ -108,6 +108,7 @@ add_library(bridgepp
|
||||
bridgepp/GRPC/GRPCUtils.cpp bridgepp/GRPC/GRPCUtils.h
|
||||
${PROTO_CPP_FILE} ${PROTO_H_FILE} ${GRPC_CPP_FILE} ${GRPC_H_FILE}
|
||||
bridgepp/Log/Log.h bridgepp/Log/Log.cpp
|
||||
bridgepp/ProcessMonitor.cpp bridgepp/ProcessMonitor.h
|
||||
bridgepp/User/User.cpp bridgepp/User/User.h
|
||||
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/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
|
||||
#define BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
|
||||
#ifndef BRIDGE_PP_TESTER_BRIDGE_UTILS_H
|
||||
#define BRIDGE_PP_TESTER_BRIDGE_UTILS_H
|
||||
|
||||
|
||||
#include <bridgepp/User/User.h>
|
||||
|
||||
|
||||
namespace bridgepp {
|
||||
namespace bridgepp
|
||||
{
|
||||
|
||||
|
||||
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.
|
||||
SPUser randomUser(); ///< Get a random user.
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
|
||||
#endif // BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
|
||||
#endif // BRIDGE_PP_TESTER_BRIDGE_UTILS_H
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_TESTER_EVENT_FACTORY_H
|
||||
#define BRIDGE_GUI_TESTER_EVENT_FACTORY_H
|
||||
#ifndef BRIDGE_PP_EVENT_FACTORY_H
|
||||
#define BRIDGE_PP_EVENT_FACTORY_H
|
||||
|
||||
|
||||
#include "bridge.grpc.pb.h"
|
||||
@ -85,4 +85,4 @@ SPStreamEvent newUserChangedEvent(QString const &userID); ///< Create a new User
|
||||
} // 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/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_RPC_CLIENT_H
|
||||
#define BRIDGE_GUI_RPC_CLIENT_H
|
||||
#ifndef BRIDGE_PP_RPC_CLIENT_H
|
||||
#define BRIDGE_PP_RPC_CLIENT_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/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_GRPC_UTILS_H
|
||||
#define BRIDGE_GUI_GRPC_UTILS_H
|
||||
#ifndef BRIDGE_PP_GRPC_UTILS_H
|
||||
#define BRIDGE_PP_GRPC_UTILS_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/>.
|
||||
|
||||
|
||||
#include "BridgeMonitor.h"
|
||||
#include <bridgepp/Exception/Exception.h>
|
||||
#include "ProcessMonitor.h"
|
||||
#include "Exception/Exception.h"
|
||||
|
||||
|
||||
using namespace bridgepp;
|
||||
|
||||
|
||||
namespace
|
||||
namespace bridgepp
|
||||
{
|
||||
|
||||
|
||||
/// \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.
|
||||
/// \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] exePath The path of the executable.
|
||||
/// \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)
|
||||
, exePath_(exePath)
|
||||
, args_(args)
|
||||
{
|
||||
QFileInfo fileInfo(exePath);
|
||||
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()))
|
||||
throw Exception("Invalid bridge executable");
|
||||
throw Exception(QString("Invalid %1 executable").arg(fileInfo.baseName()));
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
//
|
||||
//****************************************************************************************************************************************************
|
||||
void BridgeMonitor::run()
|
||||
void ProcessMonitor::run()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -92,9 +65,9 @@ void BridgeMonitor::run()
|
||||
}
|
||||
|
||||
status_.running = false;
|
||||
status_.returnCode = p.exitCode();
|
||||
status_.returnCode = p.exitCode();
|
||||
|
||||
emit processExited(status_.returnCode );
|
||||
emit processExited(status_.returnCode);
|
||||
emit finished();
|
||||
}
|
||||
catch (Exception const &e)
|
||||
@ -103,10 +76,14 @@ void BridgeMonitor::run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return status of the monitored process
|
||||
//****************************************************************************************************************************************************
|
||||
const BridgeMonitor::MonitorStatus& BridgeMonitor::getStatus()
|
||||
const ProcessMonitor::MonitorStatus &ProcessMonitor::getStatus()
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
|
||||
} // namespace bridgepp
|
||||
@ -16,48 +16,52 @@
|
||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_BRIDGE_MONITOR_H
|
||||
#define BRIDGE_GUI_BRIDGE_MONITOR_H
|
||||
#ifndef BRIDGE_PP_PROCESS_MONITOR_H
|
||||
#define BRIDGE_PP_PROCESS_MONITOR_H
|
||||
|
||||
|
||||
#include <bridgepp/Worker/Worker.h>
|
||||
#include "Worker/Worker.h"
|
||||
|
||||
|
||||
//**********************************************************************************************************************
|
||||
/// \brief Bridge process launcher and monitor class.
|
||||
//**********************************************************************************************************************
|
||||
class BridgeMonitor: public bridgepp::Worker
|
||||
namespace bridgepp
|
||||
{
|
||||
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;
|
||||
int returnCode = 0;
|
||||
qint64 pid = 0;
|
||||
};
|
||||
|
||||
public: // member functions.
|
||||
BridgeMonitor(QString const& exePath, QStringList const &args, QObject *parent); ///< Default constructor.
|
||||
BridgeMonitor(BridgeMonitor const&) = delete; ///< Disabled copy-constructor.
|
||||
BridgeMonitor(BridgeMonitor&&) = delete; ///< Disabled assignment copy-constructor.
|
||||
~BridgeMonitor() override = default; ///< Destructor.
|
||||
BridgeMonitor& operator=(BridgeMonitor const&) = delete; ///< Disabled assignment operator.
|
||||
BridgeMonitor& operator=(BridgeMonitor&&) = delete; ///< Disabled move assignment operator.
|
||||
ProcessMonitor(QString const &exePath, QStringList const &args, QObject *parent); ///< Default constructor.
|
||||
ProcessMonitor(ProcessMonitor const &) = delete; ///< Disabled copy-constructor.
|
||||
ProcessMonitor(ProcessMonitor &&) = delete; ///< Disabled assignment copy-constructor.
|
||||
~ProcessMonitor() override = default; ///< Destructor.
|
||||
ProcessMonitor &operator=(ProcessMonitor const &) = delete; ///< Disabled assignment operator.
|
||||
ProcessMonitor &operator=(ProcessMonitor &&) = delete; ///< Disabled move assignment operator.
|
||||
void run() override; ///< Run the worker.
|
||||
MonitorStatus const &getStatus();
|
||||
|
||||
const MonitorStatus& getStatus();
|
||||
signals:
|
||||
void processExited(int code); ///< Slot for the exiting of the process.
|
||||
|
||||
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.
|
||||
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/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_USER_H
|
||||
#define BRIDGE_GUI_USER_H
|
||||
#ifndef BRIDGE_PP_USER_H
|
||||
#define BRIDGE_PP_USER_H
|
||||
|
||||
|
||||
namespace bridgepp
|
||||
@ -127,4 +127,4 @@ private: // data members.
|
||||
} // 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.
|
||||
//****************************************************************************************************************************************************
|
||||
|
||||
@ -41,6 +41,7 @@ public: // member functions.
|
||||
Overseer &operator=(Overseer const &) = delete; ///< Disabled assignment operator.
|
||||
Overseer &operator=(Overseer &&) = delete; ///< Disabled move assignment operator.
|
||||
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.
|
||||
|
||||
public slots:
|
||||
|
||||
@ -64,7 +64,7 @@ func grpcUserFromBridge(user types.User) *User {
|
||||
Username: user.Username(),
|
||||
AvatarText: getInitials(user.Username()),
|
||||
LoggedIn: user.IsConnected(),
|
||||
SplitMode: user.IsCombinedAddressMode(),
|
||||
SplitMode: !user.IsCombinedAddressMode(),
|
||||
SetupGuideSeen: true, // users listed have already seen the setup guide.
|
||||
UsedBytes: user.UsedBytes(),
|
||||
TotalBytes: user.TotalBytes(),
|
||||
|
||||
Reference in New Issue
Block a user