mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-11 05:06:51 +00:00
106 lines
4.5 KiB
C++
106 lines
4.5 KiB
C++
// Copyright (c) 2023 Proton AG
|
|
//
|
|
// This file is part of Proton Mail Bridge.
|
|
//
|
|
// Proton Mail Bridge is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Proton Mail Bridge is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
#include "AppController.h"
|
|
#include "QMLBackend.h"
|
|
#include "SentryUtils.h"
|
|
#include <bridgepp/GRPC/GRPCClient.h>
|
|
#include <bridgepp/Exception/Exception.h>
|
|
#include <bridgepp/ProcessMonitor.h>
|
|
#include <bridgepp/Log/Log.h>
|
|
#include <sentry.h>
|
|
|
|
|
|
using namespace bridgepp;
|
|
|
|
namespace {
|
|
QString const noWindowFlag = "--no-window"; ///< The no-window command-line flag.
|
|
}
|
|
|
|
//****************************************************************************************************************************************************
|
|
/// \return The AppController instance.
|
|
//****************************************************************************************************************************************************
|
|
AppController &app() {
|
|
static AppController app;
|
|
return app;
|
|
}
|
|
|
|
|
|
//****************************************************************************************************************************************************
|
|
//
|
|
//****************************************************************************************************************************************************
|
|
AppController::AppController()
|
|
: backend_(std::make_unique<QMLBackend>())
|
|
, grpc_(std::make_unique<GRPCClient>())
|
|
, log_(std::make_unique<Log>()) {
|
|
}
|
|
|
|
|
|
//****************************************************************************************************************************************************
|
|
/// \return The bridge worker, which can be null if the application was run in 'attach' mode (-a command-line switch).
|
|
//****************************************************************************************************************************************************
|
|
ProcessMonitor *AppController::bridgeMonitor() const {
|
|
if (!bridgeOverseer_) {
|
|
return nullptr;
|
|
}
|
|
|
|
// null bridgeOverseer is OK, it means we run in 'attached' mode (app attached to an already running instance of Bridge).
|
|
// 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");
|
|
}
|
|
|
|
return monitor;
|
|
}
|
|
|
|
|
|
//****************************************************************************************************************************************************
|
|
/// \param[in] function The function that caught the exception.
|
|
/// \param[in] message The error message.
|
|
/// \param[in] details The details for the error.
|
|
//****************************************************************************************************************************************************
|
|
void AppController::onFatalError(QString const &function, QString const &message, QString const& details) {
|
|
QString fullMessage = QString("%1(): %2").arg(function, message);
|
|
if (!details.isEmpty())
|
|
fullMessage += "\n\nDetails:\n" + details;
|
|
sentry_uuid_s const uuid = reportSentryException(SENTRY_LEVEL_ERROR, "AppController got notified of a fatal error", "Exception",
|
|
fullMessage.toLocal8Bit());
|
|
QMessageBox::critical(nullptr, tr("Error"), message);
|
|
restart(true);
|
|
log().fatal(QString("reportID: %1 Captured exception: %2").arg(QByteArray(uuid.bytes, 16).toHex(), fullMessage));
|
|
qApp->exit(EXIT_FAILURE);
|
|
}
|
|
|
|
void AppController::restart(bool isCrashing) {
|
|
if (!launcher_.isEmpty()) {
|
|
QProcess p;
|
|
log_->info(QString("Restarting - App : %1 - Args : %2").arg(launcher_,launcherArgs_.join(" ")));
|
|
QStringList args = launcherArgs_;
|
|
if (isCrashing)
|
|
args.append(noWindowFlag);
|
|
|
|
p.startDetached(launcher_, args);
|
|
p.waitForStarted();
|
|
}
|
|
}
|
|
|
|
void AppController::setLauncherArgs(const QString& launcher, const QStringList& args){
|
|
launcher_ = launcher;
|
|
launcherArgs_ = args;
|
|
} |