backend.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright 2019 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <functional>
  6. #include <optional>
  7. #include <string>
  8. #include <string_view>
  9. #include "common/common_types.h"
  10. #include "core/file_sys/vfs_types.h"
  11. #include "core/hle/kernel/k_readable_event.h"
  12. #include "core/hle/kernel/writable_event.h"
  13. #include "core/hle/result.h"
  14. namespace Core {
  15. class System;
  16. }
  17. namespace Kernel {
  18. class KernelCore;
  19. }
  20. namespace Service::BCAT {
  21. struct DeliveryCacheProgressImpl;
  22. using DirectoryGetter = std::function<FileSys::VirtualDir(u64)>;
  23. using Passphrase = std::array<u8, 0x20>;
  24. struct TitleIDVersion {
  25. u64 title_id;
  26. u64 build_id;
  27. };
  28. using DirectoryName = std::array<char, 0x20>;
  29. using FileName = std::array<char, 0x20>;
  30. struct DeliveryCacheProgressImpl {
  31. enum class Status : s32 {
  32. None = 0x0,
  33. Queued = 0x1,
  34. Connecting = 0x2,
  35. ProcessingDataList = 0x3,
  36. Downloading = 0x4,
  37. Committing = 0x5,
  38. Done = 0x9,
  39. };
  40. Status status;
  41. ResultCode result = RESULT_SUCCESS;
  42. DirectoryName current_directory;
  43. FileName current_file;
  44. s64 current_downloaded_bytes; ///< Bytes downloaded on current file.
  45. s64 current_total_bytes; ///< Bytes total on current file.
  46. s64 total_downloaded_bytes; ///< Bytes downloaded on overall download.
  47. s64 total_bytes; ///< Bytes total on overall download.
  48. INSERT_PADDING_BYTES(
  49. 0x198); ///< Appears to be unused in official code, possibly reserved for future use.
  50. };
  51. static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200,
  52. "DeliveryCacheProgressImpl has incorrect size.");
  53. // A class to manage the signalling to the game about BCAT download progress.
  54. // Some of this class is implemented in module.cpp to avoid exposing the implementation structure.
  55. class ProgressServiceBackend {
  56. friend class IBcatService;
  57. public:
  58. // Clients should call this with true if any of the functions are going to be called from a
  59. // non-HLE thread and this class need to lock the hle mutex. (default is false)
  60. void SetNeedHLELock(bool need);
  61. // Sets the number of bytes total in the entire download.
  62. void SetTotalSize(u64 size);
  63. // Notifies the application that the backend has started connecting to the server.
  64. void StartConnecting();
  65. // Notifies the application that the backend has begun accumulating and processing metadata.
  66. void StartProcessingDataList();
  67. // Notifies the application that a file is starting to be downloaded.
  68. void StartDownloadingFile(std::string_view dir_name, std::string_view file_name, u64 file_size);
  69. // Updates the progress of the current file to the size passed.
  70. void UpdateFileProgress(u64 downloaded);
  71. // Notifies the application that the current file has completed download.
  72. void FinishDownloadingFile();
  73. // Notifies the application that all files in this directory have completed and are being
  74. // finalized.
  75. void CommitDirectory(std::string_view dir_name);
  76. // Notifies the application that the operation completed with result code result.
  77. void FinishDownload(ResultCode result);
  78. private:
  79. explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
  80. std::shared_ptr<Kernel::KReadableEvent> GetEvent() const;
  81. DeliveryCacheProgressImpl& GetImpl();
  82. void SignalUpdate() const;
  83. DeliveryCacheProgressImpl impl{};
  84. Kernel::EventPair event;
  85. bool need_hle_lock = false;
  86. };
  87. // A class representing an abstract backend for BCAT functionality.
  88. class Backend {
  89. public:
  90. explicit Backend(DirectoryGetter getter);
  91. virtual ~Backend();
  92. // Called when the backend is needed to synchronize the data for the game with title ID and
  93. // version in title. A ProgressServiceBackend object is provided to alert the application of
  94. // status.
  95. virtual bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) = 0;
  96. // Very similar to Synchronize, but only for the directory provided. Backends should not alter
  97. // the data for any other directories.
  98. virtual bool SynchronizeDirectory(TitleIDVersion title, std::string name,
  99. ProgressServiceBackend& progress) = 0;
  100. // Removes all cached data associated with title id provided.
  101. virtual bool Clear(u64 title_id) = 0;
  102. // Sets the BCAT Passphrase to be used with the associated title ID.
  103. virtual void SetPassphrase(u64 title_id, const Passphrase& passphrase) = 0;
  104. // Gets the launch parameter used by AM associated with the title ID and version provided.
  105. virtual std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) = 0;
  106. protected:
  107. DirectoryGetter dir_getter;
  108. };
  109. // A backend of BCAT that provides no operation.
  110. class NullBackend : public Backend {
  111. public:
  112. explicit NullBackend(DirectoryGetter getter);
  113. ~NullBackend() override;
  114. bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override;
  115. bool SynchronizeDirectory(TitleIDVersion title, std::string name,
  116. ProgressServiceBackend& progress) override;
  117. bool Clear(u64 title_id) override;
  118. void SetPassphrase(u64 title_id, const Passphrase& passphrase) override;
  119. std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override;
  120. };
  121. std::unique_ptr<Backend> CreateBackendFromSettings(Core::System& system, DirectoryGetter getter);
  122. } // namespace Service::BCAT