From cc1d7048b590a6f39ddf6d3065197ce475912403 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Sat, 12 Oct 2019 09:23:40 -0400
Subject: [PATCH] bcat: Remove use of global system accessors

Removes all uses of the global system accessor within the BCAT
interface.
---
 src/core/hle/service/am/am.cpp                |  5 ++--
 src/core/hle/service/bcat/backend/backend.cpp |  4 +--
 src/core/hle/service/bcat/backend/backend.h   | 12 ++++++--
 src/core/hle/service/bcat/backend/boxcat.cpp  | 29 ++++++++++++-------
 src/core/hle/service/bcat/backend/boxcat.h    | 10 +++++--
 src/core/hle/service/bcat/module.cpp          | 24 ++++++++-------
 6 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 941ebc93a6..3a32d5b417 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1140,8 +1140,9 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called, kind={:08X}", static_cast<u8>(kind));
 
     if (kind == LaunchParameterKind::ApplicationSpecific && !launch_popped_application_specific) {
-        const auto backend = BCAT::CreateBackendFromSettings(
-            [this](u64 tid) { return system.GetFileSystemController().GetBCATDirectory(tid); });
+        const auto backend = BCAT::CreateBackendFromSettings(system, [this](u64 tid) {
+            return system.GetFileSystemController().GetBCATDirectory(tid);
+        });
         const auto build_id_full = system.GetCurrentProcessBuildID();
         u64 build_id{};
         std::memcpy(&build_id, build_id_full.data(), sizeof(u64));
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index 9d6946bc5d..b86fda29a6 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -10,8 +10,8 @@
 
 namespace Service::BCAT {
 
-ProgressServiceBackend::ProgressServiceBackend(std::string_view event_name) {
-    auto& kernel{Core::System::GetInstance().Kernel()};
+ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
+                                               std::string_view event_name) {
     event = Kernel::WritableEvent::CreateEventPair(
         kernel, Kernel::ResetType::Automatic,
         std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h
index 51dbd33162..ea4b16ad0a 100644
--- a/src/core/hle/service/bcat/backend/backend.h
+++ b/src/core/hle/service/bcat/backend/backend.h
@@ -15,6 +15,14 @@
 #include "core/hle/kernel/writable_event.h"
 #include "core/hle/result.h"
 
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+class KernelCore;
+}
+
 namespace Service::BCAT {
 
 struct DeliveryCacheProgressImpl;
@@ -88,7 +96,7 @@ public:
     void FinishDownload(ResultCode result);
 
 private:
-    explicit ProgressServiceBackend(std::string_view event_name);
+    explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
 
     Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent() const;
     DeliveryCacheProgressImpl& GetImpl();
@@ -145,6 +153,6 @@ public:
     std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override;
 };
 
-std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter);
+std::unique_ptr<Backend> CreateBackendFromSettings(Core::System& system, DirectoryGetter getter);
 
 } // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index 64022982bf..918159e112 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -104,14 +104,15 @@ std::string GetZIPFilePath(u64 title_id) {
 
 // If the error is something the user should know about (build ID mismatch, bad client version),
 // display an error.
-void HandleDownloadDisplayResult(DownloadResult res) {
+void HandleDownloadDisplayResult(const AM::Applets::AppletManager& applet_manager,
+                                 DownloadResult res) {
     if (res == DownloadResult::Success || res == DownloadResult::NoResponse ||
         res == DownloadResult::GeneralWebError || res == DownloadResult::GeneralFSError ||
         res == DownloadResult::NoMatchTitleId || res == DownloadResult::InvalidContentType) {
         return;
     }
 
-    const auto& frontend{Core::System::GetInstance().GetAppletManager().GetAppletFrontendSet()};
+    const auto& frontend{applet_manager.GetAppletFrontendSet()};
     frontend.error->ShowCustomErrorText(
         ResultCode(-1), "There was an error while attempting to use Boxcat.",
         DOWNLOAD_RESULT_LOG_MESSAGES[static_cast<std::size_t>(res)], [] {});
@@ -264,12 +265,13 @@ private:
     u64 build_id;
 };
 
-Boxcat::Boxcat(DirectoryGetter getter) : Backend(std::move(getter)) {}
+Boxcat::Boxcat(AM::Applets::AppletManager& applet_manager_, DirectoryGetter getter)
+    : Backend(std::move(getter)), applet_manager{applet_manager_} {}
 
 Boxcat::~Boxcat() = default;
 
-void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
-                         ProgressServiceBackend& progress,
+void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGetter dir_getter,
+                         TitleIDVersion title, ProgressServiceBackend& progress,
                          std::optional<std::string> dir_name = {}) {
     progress.SetNeedHLELock(true);
 
@@ -295,7 +297,7 @@ void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
             FileUtil::Delete(zip_path);
         }
 
-        HandleDownloadDisplayResult(res);
+        HandleDownloadDisplayResult(applet_manager, res);
         progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
         return;
     }
@@ -364,17 +366,24 @@ void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
 
 bool Boxcat::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) {
     is_syncing.exchange(true);
-    std::thread([this, title, &progress] { SynchronizeInternal(dir_getter, title, progress); })
+
+    std::thread([this, title, &progress] {
+        SynchronizeInternal(applet_manager, dir_getter, title, progress);
+    })
         .detach();
+
     return true;
 }
 
 bool Boxcat::SynchronizeDirectory(TitleIDVersion title, std::string name,
                                   ProgressServiceBackend& progress) {
     is_syncing.exchange(true);
-    std::thread(
-        [this, title, name, &progress] { SynchronizeInternal(dir_getter, title, progress, name); })
+
+    std::thread([this, title, name, &progress] {
+        SynchronizeInternal(applet_manager, dir_getter, title, progress, name);
+    })
         .detach();
+
     return true;
 }
 
@@ -420,7 +429,7 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
                 FileUtil::Delete(path);
             }
 
-            HandleDownloadDisplayResult(res);
+            HandleDownloadDisplayResult(applet_manager, res);
             return std::nullopt;
         }
     }
diff --git a/src/core/hle/service/bcat/backend/boxcat.h b/src/core/hle/service/bcat/backend/boxcat.h
index 6011511899..d65b42e583 100644
--- a/src/core/hle/service/bcat/backend/boxcat.h
+++ b/src/core/hle/service/bcat/backend/boxcat.h
@@ -9,6 +9,10 @@
 #include <optional>
 #include "core/hle/service/bcat/backend/backend.h"
 
+namespace Service::AM::Applets {
+class AppletManager;
+}
+
 namespace Service::BCAT {
 
 struct EventStatus {
@@ -20,12 +24,13 @@ struct EventStatus {
 /// Boxcat is yuzu's custom backend implementation of Nintendo's BCAT service. It is free to use and
 /// doesn't require a switch or nintendo account. The content is controlled by the yuzu team.
 class Boxcat final : public Backend {
-    friend void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
+    friend void SynchronizeInternal(AM::Applets::AppletManager& applet_manager,
+                                    DirectoryGetter dir_getter, TitleIDVersion title,
                                     ProgressServiceBackend& progress,
                                     std::optional<std::string> dir_name);
 
 public:
-    explicit Boxcat(DirectoryGetter getter);
+    explicit Boxcat(AM::Applets::AppletManager& applet_manager_, DirectoryGetter getter);
     ~Boxcat() override;
 
     bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override;
@@ -53,6 +58,7 @@ private:
 
     class Client;
     std::unique_ptr<Client> client;
+    AM::Applets::AppletManager& applet_manager;
 };
 
 } // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 4e4aa758be..6d9d1527da 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -125,7 +125,11 @@ private:
 class IBcatService final : public ServiceFramework<IBcatService> {
 public:
     explicit IBcatService(Core::System& system_, Backend& backend_)
-        : ServiceFramework("IBcatService"), system{system_}, backend{backend_} {
+        : ServiceFramework("IBcatService"), system{system_}, backend{backend_},
+          progress{{
+              ProgressServiceBackend{system_.Kernel(), "Normal"},
+              ProgressServiceBackend{system_.Kernel(), "Directory"},
+          }} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {10100, &IBcatService::RequestSyncDeliveryCache, "RequestSyncDeliveryCache"},
@@ -249,10 +253,7 @@ private:
     Core::System& system;
     Backend& backend;
 
-    std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress{
-        ProgressServiceBackend{"Normal"},
-        ProgressServiceBackend{"Directory"},
-    };
+    std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress;
 };
 
 void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) {
@@ -557,12 +558,12 @@ void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId(
     rb.PushIpcInterface<IDeliveryCacheStorageService>(fsc.GetBCATDirectory(title_id));
 }
 
-std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter) {
-    const auto backend = Settings::values.bcat_backend;
-
+std::unique_ptr<Backend> CreateBackendFromSettings([[maybe_unused]] Core::System& system,
+                                                   DirectoryGetter getter) {
 #ifdef YUZU_ENABLE_BOXCAT
-    if (backend == "boxcat")
-        return std::make_unique<Boxcat>(std::move(getter));
+    if (Settings::values.bcat_backend == "boxcat") {
+        return std::make_unique<Boxcat>(system.GetAppletManager(), std::move(getter));
+    }
 #endif
 
     return std::make_unique<NullBackend>(std::move(getter));
@@ -571,7 +572,8 @@ std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter) {
 Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
                              FileSystem::FileSystemController& fsc_, const char* name)
     : ServiceFramework(name), fsc{fsc_}, module{std::move(module_)},
-      backend{CreateBackendFromSettings([&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })},
+      backend{CreateBackendFromSettings(system_,
+                                        [&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })},
       system{system_} {}
 
 Module::Interface::~Interface() = default;