From bd14afd9a0ff37ac360d6716944b99a81be4a159 Mon Sep 17 00:00:00 2001 From: Miguel <81558772+Miguel-hrvs@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:17:58 +0100 Subject: [PATCH] remove the telemetry except from the renderers as I'm not being capable to remove it from there --- src/citra/citra.cpp | 3 - src/citra_qt/compatdb.cpp | 10 +- src/citra_qt/compatdb.h | 8 +- src/citra_qt/configuration/configure_web.cpp | 28 +-- src/citra_qt/configuration/configure_web.h | 1 - src/citra_qt/configuration/configure_web.ui | 50 ----- src/citra_qt/main.cpp | 29 +-- src/common/CMakeLists.txt | 2 - src/common/telemetry.cpp | 91 --------- src/common/telemetry.h | 198 ------------------- src/core/CMakeLists.txt | 2 - src/core/core.cpp | 13 -- src/core/core.h | 13 +- src/core/hle/service/apt/apt.cpp | 5 - src/core/loader/ncch.cpp | 4 - src/core/telemetry_session.cpp | 175 ---------------- src/core/telemetry_session.h | 90 --------- src/web_service/CMakeLists.txt | 2 - src/web_service/telemetry_json.cpp | 129 ------------ src/web_service/telemetry_json.h | 45 ----- 20 files changed, 12 insertions(+), 886 deletions(-) diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index 8488b64df..52d64f1e8 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -39,7 +39,6 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/cfg/cfg.h" #include "core/movie.h" -#include "core/telemetry_session.h" #include "input_common/main.h" #include "network/network.h" #include "video_core/gpu.h" @@ -436,8 +435,6 @@ int main(int argc, char** argv) { break; } - system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL"); - if (use_multiplayer) { if (auto member = Network::GetRoomMember().lock()) { member->BindOnChatMessageRecieved(OnMessageReceived); diff --git a/src/citra_qt/compatdb.cpp b/src/citra_qt/compatdb.cpp index ca8f5870a..62066b6ff 100644 --- a/src/citra_qt/compatdb.cpp +++ b/src/citra_qt/compatdb.cpp @@ -7,14 +7,12 @@ #include #include #include "citra_qt/compatdb.h" -#include "common/telemetry.h" #include "core/core.h" -#include "core/telemetry_session.h" #include "ui_compatdb.h" -CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent) +CompatDB::CompatDB(QWidget* parent) : QWizard(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), - ui{std::make_unique()}, telemetry_session{telemetry_session_} { + ui{std::make_unique()} { ui->setupUi(this); connect(ui->radioButton_Perfect, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(ui->radioButton_Great, &QRadioButton::clicked, this, &CompatDB::EnableNext); @@ -52,15 +50,11 @@ void CompatDB::Submit() { case CompatDBPage::Final: back(); LOG_DEBUG(Frontend, "Compatibility Rating: {}", compatibility->checkedId()); - telemetry_session.AddField(Common::Telemetry::FieldType::UserFeedback, "Compatibility", - compatibility->checkedId()); button(NextButton)->setEnabled(false); button(NextButton)->setText(tr("Submitting")); button(CancelButton)->setVisible(false); - testcase_watcher.setFuture( - QtConcurrent::run([this] { return telemetry_session.SubmitTestcase(); })); break; default: LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); diff --git a/src/citra_qt/compatdb.h b/src/citra_qt/compatdb.h index b8ae5e209..5381f67f7 100644 --- a/src/citra_qt/compatdb.h +++ b/src/citra_qt/compatdb.h @@ -8,10 +8,6 @@ #include #include -namespace Core { -class TelemetrySession; -} - namespace Ui { class CompatDB; } @@ -20,7 +16,7 @@ class CompatDB : public QWizard { Q_OBJECT public: - explicit CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent = nullptr); + explicit CompatDB(QWidget* parent = nullptr); ~CompatDB(); private: @@ -31,6 +27,4 @@ private: void Submit(); void OnTestcaseSubmitted(); void EnableNext(); - - Core::TelemetrySession& telemetry_session; }; diff --git a/src/citra_qt/configuration/configure_web.cpp b/src/citra_qt/configuration/configure_web.cpp index b9a15b6ec..024220ab7 100644 --- a/src/citra_qt/configuration/configure_web.cpp +++ b/src/citra_qt/configuration/configure_web.cpp @@ -7,7 +7,6 @@ #include #include "citra_qt/configuration/configure_web.h" #include "citra_qt/uisettings.h" -#include "core/telemetry_session.h" #include "network/network_settings.h" #include "ui_configure_web.h" @@ -39,8 +38,6 @@ static std::string TokenFromDisplayToken(const std::string& display_token) { ConfigureWeb::ConfigureWeb(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { ui->setupUi(this); - connect(ui->button_regenerate_telemetry_id, &QPushButton::clicked, this, - &ConfigureWeb::RefreshTelemetryID); connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin); connect(&verify_watcher, &QFutureWatcher::finished, this, &ConfigureWeb::OnLoginVerified); @@ -54,12 +51,6 @@ ConfigureWeb::~ConfigureWeb() = default; void ConfigureWeb::SetConfiguration() { ui->web_credentials_disclaimer->setWordWrap(true); - ui->telemetry_learn_more->setOpenExternalLinks(true); - ui->telemetry_learn_more->setText(tr("Learn more")); ui->web_signup_link->setOpenExternalLinks(true); ui->web_signup_link->setText( @@ -70,8 +61,6 @@ void ConfigureWeb::SetConfiguration() { tr("What is my token?")); - ui->toggle_telemetry->setChecked(NetSettings::values.enable_telemetry); - if (NetSettings::values.citra_username.empty()) { ui->username->setText(tr("Unspecified")); } else { @@ -83,15 +72,11 @@ void ConfigureWeb::SetConfiguration() { // Connect after setting the values, to avoid calling OnLoginChanged now connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged); - ui->label_telemetry_id->setText( - tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper())); user_verified = true; - ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence.GetValue()); } void ConfigureWeb::ApplyConfiguration() { - NetSettings::values.enable_telemetry = ui->toggle_telemetry->isChecked(); UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked(); if (user_verified) { NetSettings::values.citra_username = @@ -105,12 +90,6 @@ void ConfigureWeb::ApplyConfiguration() { } } -void ConfigureWeb::RefreshTelemetryID() { - const u64 new_telemetry_id{Core::RegenerateTelemetryId()}; - ui->label_telemetry_id->setText( - tr("Telemetry ID: 0x%1").arg(QString::number(new_telemetry_id, 16).toUpper())); -} - void ConfigureWeb::OnLoginChanged() { if (ui->edit_token->text().isEmpty()) { user_verified = true; @@ -131,7 +110,12 @@ void ConfigureWeb::VerifyLogin() { verify_watcher.setFuture(QtConcurrent::run( [username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()), token = TokenFromDisplayToken(ui->edit_token->text().toStdString())] { - return Core::VerifyLogin(username, token); +#ifdef ENABLE_WEB_SERVICE + return WebService::VerifyLogin(Settings::values.web_api_url.GetValue(), username, + token); +#else + return false; +#endif })); } diff --git a/src/citra_qt/configuration/configure_web.h b/src/citra_qt/configuration/configure_web.h index a9b2566f8..81c0b87bf 100644 --- a/src/citra_qt/configuration/configure_web.h +++ b/src/citra_qt/configuration/configure_web.h @@ -25,7 +25,6 @@ public: void SetWebServiceConfigEnabled(bool enabled); private: - void RefreshTelemetryID(); void OnLoginChanged(); void VerifyLogin(); void OnLoginVerified(); diff --git a/src/citra_qt/configuration/configure_web.ui b/src/citra_qt/configuration/configure_web.ui index c87cf48e6..ff7d1dfbc 100644 --- a/src/citra_qt/configuration/configure_web.ui +++ b/src/citra_qt/configuration/configure_web.ui @@ -119,56 +119,6 @@ - - - - Telemetry - - - - - - Share anonymous usage data with the Citra team - - - - - - - Learn more - - - - - - - - - Telemetry ID: - - - - - - - - 0 - 0 - - - - Qt::RightToLeft - - - Regenerate - - - - - - - - diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 5d8b4204b..1875a115e 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -15,7 +15,6 @@ #include #include #include -#include "core/telemetry_session.h" #ifdef __APPLE__ #include // for chdir #endif @@ -128,27 +127,6 @@ constexpr int default_mouse_timeout = 2500; * is a bitfield "callout_flags" options, used to track if a message has already been shown to the * user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones. */ -enum class CalloutFlag : uint32_t { - Telemetry = 0x1, -}; - -void GMainWindow::ShowTelemetryCallout() { - if (UISettings::values.callout_flags.GetValue() & - static_cast(CalloutFlag::Telemetry)) { - return; - } - - UISettings::values.callout_flags = - UISettings::values.callout_flags.GetValue() | static_cast(CalloutFlag::Telemetry); - const QString telemetry_message = - tr("Anonymous " - "data is collected to help improve Citra. " - "

Would you like to share your usage data with us?"); - if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) == QMessageBox::Yes) { - NetSettings::values.enable_telemetry = true; - system.ApplySettings(); - } -} const int GMainWindow::max_recent_files_item; @@ -263,9 +241,6 @@ GMainWindow::GMainWindow(Core::System& system_) game_list->LoadCompatibilityList(); game_list->PopulateAsync(UISettings::values.game_dirs); - // Show one-time "callout" messages to the user - ShowTelemetryCallout(); - mouse_hide_timer.setInterval(default_mouse_timeout); connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor); connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::OnMouseActivity); @@ -1244,7 +1219,6 @@ bool GMainWindow::LoadROM(const QString& filename) { game_path = filename; - system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); return true; } @@ -1988,7 +1962,7 @@ void GMainWindow::OnLoadComplete() { void GMainWindow::OnMenuReportCompatibility() { if (!NetSettings::values.citra_token.empty() && !NetSettings::values.citra_username.empty()) { - CompatDB compatdb{system.TelemetrySession(), this}; + CompatDB compatdb{this}; compatdb.exec(); } else { QMessageBox::critical(this, tr("Missing Citra Account"), @@ -3241,3 +3215,4 @@ int main(int argc, char* argv[]) { detached_tasks.WaitForAllTasks(); return result; } + diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f8c953a60..567831249 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -130,8 +130,6 @@ add_library(citra_common STATIC string_util.cpp string_util.h swap.h - telemetry.cpp - telemetry.h texture.cpp texture.h thread.cpp diff --git a/src/common/telemetry.cpp b/src/common/telemetry.cpp index e5fd193ef..8b1378917 100644 --- a/src/common/telemetry.cpp +++ b/src/common/telemetry.cpp @@ -1,92 +1 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -#include -#include -#include "common/arch.h" -#include "common/assert.h" -#include "common/scm_rev.h" -#include "common/telemetry.h" - -#if CITRA_ARCH(x86_64) -#include "common/x64/cpu_detect.h" -#endif - -namespace Common::Telemetry { - -void FieldCollection::Accept(VisitorInterface& visitor) const { - for (const auto& field : fields) { - field.second->Accept(visitor); - } -} - -void FieldCollection::AddField(std::unique_ptr field) { - fields[field->GetName()] = std::move(field); -} - -template -void Field::Accept(VisitorInterface& visitor) const { - visitor.Visit(*this); -} - -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; - -void AppendBuildInfo(FieldCollection& fc) { - const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; - fc.AddField(FieldType::App, "Git_IsDirty", is_git_dirty); - fc.AddField(FieldType::App, "Git_Branch", Common::g_scm_branch); - fc.AddField(FieldType::App, "Git_Revision", Common::g_scm_rev); - fc.AddField(FieldType::App, "BuildDate", Common::g_build_date); - fc.AddField(FieldType::App, "BuildName", Common::g_build_name); -} - -void AppendCPUInfo(FieldCollection& fc) { -#if CITRA_ARCH(x86_64) - fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); - fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX512", Common::GetCPUCaps().avx512); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_BMI1", Common::GetCPUCaps().bmi1); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_BMI2", Common::GetCPUCaps().bmi2); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_FMA", Common::GetCPUCaps().fma); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_FMA4", Common::GetCPUCaps().fma4); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE", Common::GetCPUCaps().sse); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE2", Common::GetCPUCaps().sse2); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE3", Common::GetCPUCaps().sse3); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSSE3", Common::GetCPUCaps().ssse3); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE41", Common::GetCPUCaps().sse4_1); - fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE42", Common::GetCPUCaps().sse4_2); -#else - fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); -#endif -} - -void AppendOSInfo(FieldCollection& fc) { -#ifdef __APPLE__ - fc.AddField(FieldType::UserSystem, "OsPlatform", "Apple"); -#elif defined(_WIN32) - fc.AddField(FieldType::UserSystem, "OsPlatform", "Windows"); -#elif defined(__linux__) || defined(linux) || defined(__linux) - fc.AddField(FieldType::UserSystem, "OsPlatform", "Linux"); -#else - fc.AddField(FieldType::UserSystem, "OsPlatform", "Unknown"); -#endif -} - -} // namespace Common::Telemetry diff --git a/src/common/telemetry.h b/src/common/telemetry.h index ba5f0c87d..8b1378917 100644 --- a/src/common/telemetry.h +++ b/src/common/telemetry.h @@ -1,199 +1 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -#pragma once - -#include -#include -#include -#include -#include "common/common_types.h" - -namespace Common::Telemetry { - -/// Field type, used for grouping fields together in the final submitted telemetry log -enum class FieldType : u8 { - None = 0, ///< No specified field group - App, ///< Citra application fields (e.g. version, branch, etc.) - Session, ///< Emulated session fields (e.g. title ID, log, etc.) - Performance, ///< Emulated performance (e.g. fps, emulated CPU speed, etc.) - UserFeedback, ///< User submitted feedback (e.g. star rating, user notes, etc.) - UserConfig, ///< User configuration fields (e.g. emulated CPU core, renderer, etc.) - UserSystem, ///< User system information (e.g. host CPU type, RAM, etc.) -}; - -struct VisitorInterface; - -/** - * Interface class for telemetry data fields. - */ -class FieldInterface : NonCopyable { -public: - virtual ~FieldInterface() = default; - - /** - * Accept method for the visitor pattern. - * @param visitor Reference to the visitor that will visit this field. - */ - virtual void Accept(VisitorInterface& visitor) const = 0; - - /** - * Gets the name of this field. - * @returns Name of this field as a string. - */ - virtual const std::string& GetName() const = 0; -}; - -/** - * Represents a telemetry data field, i.e. a unit of data that gets logged and submitted to our - * telemetry web service. - */ -template -class Field : public FieldInterface { -public: - Field(FieldType type, std::string name, T value) - : name(std::move(name)), type(type), value(std::move(value)) {} - - Field(const Field&) = default; - Field& operator=(const Field&) = default; - - Field(Field&&) = default; - Field& operator=(Field&& other) = default; - - void Accept(VisitorInterface& visitor) const override; - - [[nodiscard]] const std::string& GetName() const override { - return name; - } - - /** - * Returns the type of the field. - */ - [[nodiscard]] FieldType GetType() const { - return type; - } - - /** - * Returns the value of the field. - */ - [[nodiscard]] const T& GetValue() const { - return value; - } - - [[nodiscard]] bool operator==(const Field& other) const { - return (type == other.type) && (name == other.name) && (value == other.value); - } - - [[nodiscard]] bool operator!=(const Field& other) const { - return !operator==(other); - } - -private: - std::string name; ///< Field name, must be unique - FieldType type{}; ///< Field type, used for grouping fields together - T value; ///< Field value -}; - -/** - * Collection of data fields that have been logged. - */ -class FieldCollection final : NonCopyable { -public: - FieldCollection() = default; - - /** - * Accept method for the visitor pattern, visits each field in the collection. - * @param visitor Reference to the visitor that will visit each field. - */ - void Accept(VisitorInterface& visitor) const; - - /** - * Creates a new field and adds it to the field collection. - * @param type Type of the field to add. - * @param name Name of the field to add. - * @param value Value for the field to add. - */ - template - void AddField(FieldType type, const char* name, T value) { - return AddField(std::make_unique>(type, name, std::move(value))); - } - - /** - * Adds a new field to the field collection. - * @param field Field to add to the field collection. - */ - void AddField(std::unique_ptr field); - -private: - std::map> fields; -}; - -/** - * Telemetry fields visitor interface class. A backend to log to a web service should implement - * this interface. - */ -struct VisitorInterface : NonCopyable { - virtual ~VisitorInterface() = default; - - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - - /// Completion method, called once all fields have been visited - virtual void Complete() = 0; - virtual bool SubmitTestcase() = 0; -}; - -/** - * Empty implementation of VisitorInterface that drops all fields. Used when a functional - * backend implementation is not available. - */ -struct NullVisitor : public VisitorInterface { - ~NullVisitor() = default; - - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - - void Complete() override {} - bool SubmitTestcase() override { - return false; - } -}; - -/// Appends build-specific information to the given FieldCollection, -/// such as branch name, revision hash, etc. -void AppendBuildInfo(FieldCollection& fc); - -/// Appends CPU-specific information to the given FieldCollection, -/// such as instruction set extensions, etc. -void AppendCPUInfo(FieldCollection& fc); - -/// Appends OS-specific information to the given FieldCollection, -/// such as platform name, etc. -void AppendOSInfo(FieldCollection& fc); - -} // namespace Common::Telemetry diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cf29c05a8..62a9cde64 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -467,8 +467,6 @@ add_library(citra_core STATIC savestate_data.h system_titles.cpp system_titles.h - telemetry_session.cpp - telemetry_session.h tracer/citrace.h tracer/recorder.cpp tracer/recorder.h diff --git a/src/core/core.cpp b/src/core/core.cpp index 7d04abf03..860d6ce47 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -47,7 +47,6 @@ #ifdef ENABLE_SCRIPTING #include "core/rpc/server.h" #endif -#include "core/telemetry_session.h" #include "network/network.h" #include "video_core/custom_textures/custom_tex_manager.h" #include "video_core/gpu.h" @@ -322,7 +321,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st restore_plugin_context.reset(); } - telemetry_session->AddInitialInfo(*app_loader); std::shared_ptr process; const Loader::ResultStatus load_result{app_loader->Load(process)}; if (Loader::ResultStatus::Success != load_result) { @@ -452,8 +450,6 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, Settings::values.output_device.GetValue()); dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue()); - telemetry_session = std::make_unique(); - #ifdef ENABLE_SCRIPTING rpc_server = std::make_unique(*this); #endif @@ -580,14 +576,6 @@ void System::RegisterImageInterface(std::shared_ptr im void System::Shutdown(bool is_deserializing) { // Log last frame performance stats const auto perf_results = GetAndResetPerfStats(); - constexpr auto performance = Common::Telemetry::FieldType::Performance; - - telemetry_session->AddField(performance, "Shutdown_EmulationSpeed", - perf_results.emulation_speed * 100.0); - telemetry_session->AddField(performance, "Shutdown_Framerate", perf_results.game_fps); - telemetry_session->AddField(performance, "Shutdown_Frametime", perf_results.frametime * 1000.0); - telemetry_session->AddField(performance, "Mean_Frametime_MS", - perf_stats ? perf_stats->GetMeanFrametime() : 0); // Shutdown emulation session is_powered_on = false; @@ -599,7 +587,6 @@ void System::Shutdown(bool is_deserializing) { app_loader.reset(); } custom_tex_manager.reset(); - telemetry_session.reset(); #ifdef ENABLE_SCRIPTING rpc_server.reset(); #endif diff --git a/src/core/core.h b/src/core/core.h index 9f7430b72..f51659cb8 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -72,7 +72,6 @@ class AppLoader; namespace Core { class ARM_Interface; -class TelemetrySession; class ExclusiveMonitor; class Timing; @@ -165,14 +164,6 @@ public: return is_powered_on; } - /** - * Returns a reference to the telemetry session for this emulation session. - * @returns Reference to the telemetry session. - */ - [[nodiscard]] Core::TelemetrySession& TelemetrySession() const { - return *telemetry_session; - } - /// Prepare the core emulation for a reschedule void PrepareReschedule(); @@ -385,9 +376,6 @@ private: /// When true, signals that a reschedule should happen bool reschedule_pending{}; - /// Telemetry session for this emulation session - std::unique_ptr telemetry_session; - std::unique_ptr gpu; /// Service manager @@ -470,3 +458,4 @@ private: } // namespace Core BOOST_CLASS_VERSION(Core::System, 1) + diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index a3befffd8..3e552dfc4 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -34,7 +34,6 @@ #include "core/hw/aes/ccm.h" #include "core/hw/aes/key.h" #include "core/loader/loader.h" -#include "core/telemetry_session.h" SERVICE_CONSTRUCT_IMPL(Service::APT::Module) @@ -274,10 +273,6 @@ void Module::APTInterface::GetSharedFont(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); - // Log in telemetry if the game uses the shared font - apt->system.TelemetrySession().AddField(Common::Telemetry::FieldType::Session, - "RequiresSharedFont", true); - if (!apt->shared_font_loaded) { // On real 3DS, font loading happens on booting. However, we load it on demand to coordinate // with CFG region auto configuration, which happens later than APT initialization. diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 6b58dc547..ca0a285df 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -26,7 +26,6 @@ #include "core/loader/smdh.h" #include "core/memory.h" #include "core/system_titles.h" -#include "core/telemetry_session.h" #include "network/network.h" namespace Loader { @@ -277,9 +276,6 @@ ResultStatus AppLoader_NCCH::Load(std::shared_ptr& process) { overlay_ncch = &update_ncch; } - system.TelemetrySession().AddField(Common::Telemetry::FieldType::Session, "ProgramId", - program_id); - if (auto room_member = Network::GetRoomMember().lock()) { Network::GameInfo game_info; ReadTitle(game_info.name); diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 8a4f94599..8b1378917 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -1,176 +1 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -#include - -#include "common/assert.h" -#include "common/common_types.h" -#include "common/file_util.h" -#include "common/logging/log.h" -#include "common/scm_rev.h" -#include "common/settings.h" -#include "core/core.h" -#include "core/loader/loader.h" -#include "core/telemetry_session.h" -#include "network/network_settings.h" - -#ifdef ENABLE_WEB_SERVICE -#include "web_service/telemetry_json.h" -#include "web_service/verify_login.h" -#endif - -namespace Core { - -namespace Telemetry = Common::Telemetry; - -static u64 GenerateTelemetryId() { - u64 telemetry_id{}; - CryptoPP::AutoSeededRandomPool rng; - rng.GenerateBlock(reinterpret_cast(&telemetry_id), sizeof(u64)); - return telemetry_id; -} - -u64 GetTelemetryId() { - u64 telemetry_id{}; - const std::string filename{FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + - "telemetry_id"}; - - if (FileUtil::Exists(filename)) { - FileUtil::IOFile file(filename, "rb"); - if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", filename); - return {}; - } - file.ReadBytes(&telemetry_id, sizeof(u64)); - } else { - FileUtil::IOFile file(filename, "wb"); - if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", filename); - return {}; - } - telemetry_id = GenerateTelemetryId(); - file.WriteBytes(&telemetry_id, sizeof(u64)); - } - - return telemetry_id; -} - -u64 RegenerateTelemetryId() { - const u64 new_telemetry_id{GenerateTelemetryId()}; - const std::string filename{FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + - "telemetry_id"}; - - FileUtil::IOFile file(filename, "wb"); - if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", filename); - return {}; - } - file.WriteBytes(&new_telemetry_id, sizeof(u64)); - return new_telemetry_id; -} - -bool VerifyLogin(const std::string& username, const std::string& token) { -#ifdef ENABLE_WEB_SERVICE - return WebService::VerifyLogin(NetSettings::values.web_api_url, username, token); -#else - return false; -#endif -} - -TelemetrySession::TelemetrySession() = default; - -TelemetrySession::~TelemetrySession() { - // Log one-time session end information - const s64 shutdown_time{std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()}; - AddField(Telemetry::FieldType::Session, "Shutdown_Time", shutdown_time); - -#ifdef ENABLE_WEB_SERVICE - auto backend = std::make_unique(NetSettings::values.web_api_url, - NetSettings::values.citra_username, - NetSettings::values.citra_token); -#else - auto backend = std::make_unique(); -#endif - - // Complete the session, submitting to the web service backend if necessary - field_collection.Accept(*backend); - if (NetSettings::values.enable_telemetry) { - backend->Complete(); - } -} - -void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { - // Log one-time top-level information - AddField(Telemetry::FieldType::None, "TelemetryId", GetTelemetryId()); - - // Log one-time session start information - const s64 init_time{std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()}; - AddField(Telemetry::FieldType::Session, "Init_Time", init_time); - std::string program_name; - const Loader::ResultStatus res{app_loader.ReadTitle(program_name)}; - if (res == Loader::ResultStatus::Success) { - AddField(Telemetry::FieldType::Session, "ProgramName", program_name); - } - - // Log application information - Telemetry::AppendBuildInfo(field_collection); - - // Log user system information - Telemetry::AppendCPUInfo(field_collection); - Telemetry::AppendOSInfo(field_collection); - - // Log user configuration information - AddField(Telemetry::FieldType::UserConfig, "Audio_SinkId", - static_cast(Settings::values.output_type.GetValue())); - AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching", - Settings::values.enable_audio_stretching.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", - Settings::values.use_cpu_jit.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", - Settings::values.resolution_factor.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit", - Settings::values.frame_limit.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_Backend", - static_cast(Settings::values.graphics_api.GetValue())); - AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader", - Settings::values.use_hw_shader.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_ShadersAccurateMul", - Settings::values.shaders_accurate_mul.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_UseShaderJit", - Settings::values.use_shader_jit.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_UseVsync", - Settings::values.use_vsync_new.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_FilterMode", - Settings::values.filter_mode.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_Render3d", - static_cast(Settings::values.render_3d.GetValue())); - AddField(Telemetry::FieldType::UserConfig, "Renderer_Factor3d", - Settings::values.factor_3d.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "Renderer_MonoRenderOption", - static_cast(Settings::values.mono_render_option.GetValue())); - AddField(Telemetry::FieldType::UserConfig, "System_IsNew3ds", - Settings::values.is_new_3ds.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "System_LLEApplets", - Settings::values.lle_applets.GetValue()); - AddField(Telemetry::FieldType::UserConfig, "System_RegionValue", - Settings::values.region_value.GetValue()); -} - -bool TelemetrySession::SubmitTestcase() { -#ifdef ENABLE_WEB_SERVICE - auto backend = std::make_unique(NetSettings::values.web_api_url, - NetSettings::values.citra_username, - NetSettings::values.citra_token); - 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 f64dd2a64..8b1378917 100644 --- a/src/core/telemetry_session.h +++ b/src/core/telemetry_session.h @@ -1,91 +1 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -#pragma once - -#include -#include -#include "common/telemetry.h" - -namespace Loader { -class AppLoader; -} - -namespace Core { - -/** - * Instruments telemetry for this emulation session. Creates a new set of telemetry fields on each - * session, logging any one-time fields. Interfaces with the telemetry backend used for submitting - * data to the web service. Submits session data on close. - */ -class TelemetrySession { -public: - explicit TelemetrySession(); - ~TelemetrySession(); - - TelemetrySession(const TelemetrySession&) = delete; - TelemetrySession& operator=(const TelemetrySession&) = delete; - - TelemetrySession(TelemetrySession&&) = delete; - TelemetrySession& operator=(TelemetrySession&&) = delete; - - /** - * Adds the initial telemetry info necessary when starting up a title. - * - * This includes information such as: - * - Telemetry ID - * - Initialization time - * - Title ID - * - Title name - * - Title file format - * - Miscellaneous settings values. - * - * @param app_loader The application loader to use to retrieve - * title-specific information. - */ - void AddInitialInfo(Loader::AppLoader& app_loader); - - /** - * Wrapper around the Telemetry::FieldCollection::AddField method. - * @param type Type of the field to add. - * @param name Name of the field to add. - * @param value Value for the field to add. - */ - template - void AddField(Common::Telemetry::FieldType type, const char* name, T value) { - field_collection.AddField(type, name, std::move(value)); - } - - /** - * Submits a Testcase. - * @returns A bool indicating whether the submission succeeded - */ - bool SubmitTestcase(); - -private: - /// Tracks all added fields for the session - Common::Telemetry::FieldCollection field_collection; -}; - -/** - * Gets TelemetryId, a unique identifier used for the user's telemetry sessions. - * @returns The current TelemetryId for the session. - */ -u64 GetTelemetryId(); - -/** - * Regenerates TelemetryId, a unique identifier used for the user's telemetry sessions. - * @returns The new TelemetryId that was generated. - */ -u64 RegenerateTelemetryId(); - -/** - * Verifies the username and token. - * @param username Citra username to use for authentication. - * @param token Citra token to use for authentication. - * @returns Future with bool indicating whether the verification succeeded - */ -bool VerifyLogin(const std::string& username, const std::string& token); - -} // namespace Core diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index c7f237425..7dabb7b45 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt @@ -2,8 +2,6 @@ add_library(web_service STATIC announce_room_json.cpp announce_room_json.h precompiled_headers.h - telemetry_json.cpp - telemetry_json.h verify_login.cpp verify_login.h verify_user_jwt.cpp diff --git a/src/web_service/telemetry_json.cpp b/src/web_service/telemetry_json.cpp index 97d19f696..8b1378917 100644 --- a/src/web_service/telemetry_json.cpp +++ b/src/web_service/telemetry_json.cpp @@ -1,130 +1 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -#include -#include "common/detached_tasks.h" -#include "common/web_result.h" -#include "web_service/telemetry_json.h" -#include "web_service/web_backend.h" - -namespace WebService { - -namespace Telemetry = Common::Telemetry; - -struct TelemetryJson::Impl { - Impl(std::string host, std::string username, std::string token) - : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} {} - - nlohmann::json& TopSection() { - return sections[static_cast(Telemetry::FieldType::None)]; - } - - const nlohmann::json& TopSection() const { - return sections[static_cast(Telemetry::FieldType::None)]; - } - - template - void Serialize(Telemetry::FieldType type, const std::string& name, T value) { - sections[static_cast(type)][name] = value; - } - - void SerializeSection(Telemetry::FieldType type, const std::string& name) { - TopSection()[name] = sections[static_cast(type)]; - } - - nlohmann::json output; - std::array sections; - std::string host; - std::string username; - std::string token; -}; - -TelemetryJson::TelemetryJson(std::string host, std::string username, std::string token) - : impl{std::make_unique(std::move(host), std::move(username), std::move(token))} {} -TelemetryJson::~TelemetryJson() = default; - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue()); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), std::string(field.GetValue())); -} - -void TelemetryJson::Visit(const Telemetry::Field& field) { - impl->Serialize(field.GetType(), field.GetName(), field.GetValue().count()); -} - -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::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}, 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 f2cb19840..8b1378917 100644 --- a/src/web_service/telemetry_json.h +++ b/src/web_service/telemetry_json.h @@ -1,46 +1 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. -#pragma once - -#include -#include -#include "common/announce_multiplayer_room.h" -#include "common/telemetry.h" - -namespace WebService { - -/** - * Implementation of VisitorInterface that serialized telemetry into JSON, and submits it to the - * Citra web service - */ -class TelemetryJson : public Common::Telemetry::VisitorInterface { -public: - TelemetryJson(std::string host, std::string username, std::string token); - ~TelemetryJson() override; - - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - void Visit(const Common::Telemetry::Field& field) override; - - void Complete() override; - bool SubmitTestcase() override; - -private: - struct Impl; - std::unique_ptr impl; -}; - -} // namespace WebService