diff --git a/src/common/telemetry.h b/src/common/telemetry.h index 8d6ab986b2..854a73fae7 100644 --- a/src/common/telemetry.h +++ b/src/common/telemetry.h @@ -153,6 +153,7 @@ struct VisitorInterface : NonCopyable { /// Completion method, called once all fields have been visited virtual void Complete() = 0; + virtual bool SubmitTestcase() = 0; }; /** @@ -178,6 +179,9 @@ struct NullVisitor : public VisitorInterface { void Visit(const Field& /*field*/) override {} void Complete() override {} + bool SubmitTestcase() override { + return false; + } }; /// Appends build-specific information to the given FieldCollection, diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 0de13edd35..a3b08c740d 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -184,4 +184,13 @@ TelemetrySession::~TelemetrySession() { backend = nullptr; } +bool TelemetrySession::SubmitTestcase() { +#ifdef ENABLE_WEB_SERVICE + field_collection.Accept(*backend); + return backend->SubmitTestcase(); +#else + return false; +#endif +} + } // namespace Core diff --git a/src/core/telemetry_session.h b/src/core/telemetry_session.h index 2a4845797c..023612b79e 100644 --- a/src/core/telemetry_session.h +++ b/src/core/telemetry_session.h @@ -31,6 +31,12 @@ public: field_collection.AddField(type, name, std::move(value)); } + /** + * Submits a Testcase. + * @returns A bool indicating whether the submission succeeded + */ + bool SubmitTestcase(); + private: Telemetry::FieldCollection field_collection; ///< Tracks all added fields for the session std::unique_ptr backend; ///< Backend interface that logs fields diff --git a/src/web_service/telemetry_json.cpp b/src/web_service/telemetry_json.cpp index 0a8f2bd9e1..9156ce8028 100644 --- a/src/web_service/telemetry_json.cpp +++ b/src/web_service/telemetry_json.cpp @@ -102,16 +102,27 @@ void TelemetryJson::Complete() { impl->SerializeSection(Telemetry::FieldType::App, "App"); impl->SerializeSection(Telemetry::FieldType::Session, "Session"); impl->SerializeSection(Telemetry::FieldType::Performance, "Performance"); - impl->SerializeSection(Telemetry::FieldType::UserFeedback, "UserFeedback"); impl->SerializeSection(Telemetry::FieldType::UserConfig, "UserConfig"); impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem"); auto content = impl->TopSection().dump(); // Send the telemetry async but don't handle the errors since they were written to the log - Common::DetachedTasks::AddTask( - [host{impl->host}, username{impl->username}, token{impl->token}, content]() { - Client{host, username, token}.PostJson("/telemetry", content, true); - }); + Common::DetachedTasks::AddTask([host{impl->host}, content]() { + Client{host, "", ""}.PostJson("/telemetry", content, true); + }); +} + +bool TelemetryJson::SubmitTestcase() { + impl->SerializeSection(Telemetry::FieldType::App, "App"); + impl->SerializeSection(Telemetry::FieldType::Session, "Session"); + impl->SerializeSection(Telemetry::FieldType::UserFeedback, "UserFeedback"); + impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem"); + + auto content = impl->TopSection().dump(); + Client client(impl->host, impl->username, impl->token); + auto value = client.PostJson("/gamedb/testcase", content, false); + + return value.result_code == Common::WebResult::Code::Success; } } // namespace WebService diff --git a/src/web_service/telemetry_json.h b/src/web_service/telemetry_json.h index 93371414ae..dfd202829a 100644 --- a/src/web_service/telemetry_json.h +++ b/src/web_service/telemetry_json.h @@ -35,6 +35,7 @@ public: void Visit(const Telemetry::Field& field) override; void Complete() override; + bool SubmitTestcase() override; private: struct Impl; diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp index 91e7542743..5f0896f848 100644 --- a/src/yuzu/compatdb.cpp +++ b/src/yuzu/compatdb.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "common/logging/log.h" #include "common/telemetry.h" #include "core/core.h" @@ -23,6 +24,8 @@ CompatDB::CompatDB(QWidget* parent) connect(ui->radioButton_IntroMenu, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(ui->radioButton_WontBoot, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(button(NextButton), &QPushButton::clicked, this, &CompatDB::Submit); + connect(&testcase_watcher, &QFutureWatcher::finished, this, + &CompatDB::OnTestcaseSubmitted); } CompatDB::~CompatDB() = default; @@ -48,18 +51,38 @@ void CompatDB::Submit() { } break; case CompatDBPage::Final: + back(); LOG_DEBUG(Frontend, "Compatibility Rating: {}", compatibility->checkedId()); Core::Telemetry().AddField(Telemetry::FieldType::UserFeedback, "Compatibility", compatibility->checkedId()); - // older versions of QT don't support the "NoCancelButtonOnLastPage" option, this is a - // workaround + + button(NextButton)->setEnabled(false); + button(NextButton)->setText(tr("Submitting")); button(QWizard::CancelButton)->setVisible(false); + + testcase_watcher.setFuture(QtConcurrent::run( + [this]() { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); })); break; default: LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); } } +void CompatDB::OnTestcaseSubmitted() { + if (!testcase_watcher.result()) { + QMessageBox::critical(this, tr("Communication error"), + tr("An error occured while sending the Testcase")); + button(NextButton)->setEnabled(true); + button(NextButton)->setText(tr("Next")); + button(QWizard::CancelButton)->setVisible(true); + } else { + next(); + // older versions of QT don't support the "NoCancelButtonOnLastPage" option, this is a + // workaround + button(QWizard::CancelButton)->setVisible(false); + } +} + void CompatDB::EnableNext() { button(NextButton)->setEnabled(true); } diff --git a/src/yuzu/compatdb.h b/src/yuzu/compatdb.h index ca0dd11d61..5381f67f79 100644 --- a/src/yuzu/compatdb.h +++ b/src/yuzu/compatdb.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include namespace Ui { @@ -19,8 +20,11 @@ public: ~CompatDB(); private: + QFutureWatcher testcase_watcher; + std::unique_ptr ui; void Submit(); + void OnTestcaseSubmitted(); void EnableNext(); };